-4

我正在尝试在视频开始播放时制作 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);再次加载但系统显示我崩溃

4

1 回答 1

1

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

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

因为你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");
                    }
                });
于 2013-02-13T12:11:07.230 回答