GCD流怎么写

时间:2013-02-13 12:06:44

标签: iphone ios objective-c ipad grand-central-dispatch

我正在尝试在视频开始播放时制作avplayer的屏幕截图,所以我需要在后台快速运行此代码,这样它就不会阻止主线程和其他控件快速同时运行,试图运行该代码GCD格式我是请不要运行请帮我做它停在我添加到我的数组的位置(在数组中我添加UIImage对象)...

if (isCaptureScreenStart)
{
    if (CMTimeGetSeconds([avPlayer currentTime])>0)
    {
        if (avFramesArray!=nil)
        {
            queue = dispatch_queue_create("array", NULL);
            dispatch_sync(queue, ^{
                [avFramesArray addObject:[self screenshotFromPlayer:avPlayer maximumSize:avPlayerLayer.frame.size :CMTimeGetSeconds([avPlayer currentTime])]];//stop at this line
                NSLog(@"count:%d",[avFramesArray count]);
                dispatch_sync(dispatch_get_main_queue(), ^{
                    NSLog(@"Frame are created:%d",[avFramesArray count]);
                    if ([avFramesArray count]==0)    
                    {
                        NSLog(@"Frame are over");
                    }
                });
            });
        }
    }
}
dispatch_release(queue);

编辑:

我想我现在需要使用dispatch_group_async这个块。请给出一些如何使用的指导原则:

if (isCaptureScreenStart)
{
    if (CMTimeGetSeconds([avPlayer currentTime])>0)
    {
        if (avFramesArray!=nil) {
            dispatch_group_async(serial_group1, serial_dispatch_queue1, ^{
                [avFramesArray addObject:[self screenshotFromPlayer:avPlayer maximumSize:avPlayerLayer.frame.size :CMTimeGetSeconds([avPlayer currentTime])]];
            });
        }
    }
    dispatch_group_notify(serial_group1, serial_dispatch_queue1, ^{
        NSLog(@"task competed");
    });
}

现在我正在使用这个块,但上面的执行是有争议的运行,如果我使用dispatch_suspend(serial_dispatch_queue1);它的停止,但我需要开始执行块然后我需要使用我还尝试使用dispatch_resume(serial_dispatch_queue1);再次加载,但系统显示崩溃

1 个答案:

答案 0 :(得分:1)

dispatch_release(queue);不要那样做,你调用它的调度队列是一个backThread,所以wat正在发生的是: -

  

您的队列在代码块执行之前被释放。

因为你的queue看起来像一个ivar,所以在dealloc中释放它。休息,你的代码看起来很好..输入一个断点并检查块是否正在执行。

修改

我不明白,你试图通过暂停队列来实现,没有必要这样做。你不需要检查块是否已经完成执行。该块将完成,然后调用dispatch_async,获取主队列并从那里更新UI。

现在,在创建队列时,在方法中懒惰地创建它。将队列作为头文件中的ivar:

@interface YourFileController : UIViewController {
    dispatch_queue_t queue;
}

然后在你的方法中修改它:

if (isCaptureScreenStart)
{
    if (CMTimeGetSeconds([avPlayer currentTime])>0)
    {
        if (avFramesArray!=nil)
        {
            if (!queue)
                queue = dispatch_queue_create("array", DISPATCH_QUEUE_SERIAL);

            dispatch_sync(queue, ^{
                [avFramesArray addObject:[self screenshotFromPlayer:avPlayer maximumSize:avPlayerLayer.frame.size :CMTimeGetSeconds([avPlayer currentTime])]];//stop at this line
                NSLog(@"count:%d",[avFramesArray count]);
                dispatch_sync(dispatch_get_main_queue(), ^{
                    NSLog(@"Frame are created:%d",[avFramesArray count]);
                    if ([avFramesArray count]==0)    
                    {
                        NSLog(@"Frame are over");
                    }
                });
            });
        }
    }
}

注意DISPATCH_QUEUE_SERIAL创建一个串行队列,这意味着提交给它的所有块都将以先进先出顺序串行执行。一旦提交了所有提交的块,队列就会停止;)..向它提交另一个块并执行块:D

这代表整个街区: -

[avFramesArray addObject:[self screenshotFromPlayer:avPlayer maximumSize:avPlayerLayer.frame.size :CMTimeGetSeconds([avPlayer currentTime])]];//stop at this line
                NSLog(@"count:%d",[avFramesArray count]);
                dispatch_sync(dispatch_get_main_queue(), ^{
                    NSLog(@"Frame are created:%d",[avFramesArray count]);
                    if ([avFramesArray count]==0)    
                    {
                        NSLog(@"Frame are over");
                    }
                });