NSOperationQueue同步问题:工作队列比主队列更新UI快

时间:2013-07-26 20:24:50

标签: objective-c multithreading synchronization nsoperation nsoperationqueue

这是我的代码:

for (NSString *framePath in self.inputFramePaths) {

        if ([weakOperation isCancelled]){
            break;
        }

        self.currentFrame = [UIImage imageWithContentsOfFile:framePath];
        CGImageDestinationAddImage(destination, self.currentFrame.CGImage, (__bridge CFDictionaryRef)frameProperties);

        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            if ([self.delegate respondsToSelector:@selector(didFinishWritingOneFrameWithSender:)]){
                [self.delegate didFinishWritingOneFrameWithSender:self];
            }
        }];
        self.currentFrameIndex++;
}

我正在将图像帧写入文件,并且在写入每个帧时,我想通知UI更新进度条并显示刚刚写入的图像。问题是工作队列比ui主队列快。结果是ui队列在接收更新时延迟。 self.currentFrameIndex每次在工作队列中递增1,在ui队列中它会像这样延迟:

工作人员队列:0,1,2,3,4,5,6,7,8,9

UI主队列:0,2,4,5,6,7,9,9,9,9

如果我有更大的帧数,延迟将会扩大。我想有办法确保工作队列等待UI队列,并保证执行顺序。但由于我更关心处理速度,我只想看看处理的进度。有没有办法跳过迟到的事件,并跟上处理?如果我打印currentFrameIndex:

,我想要这样的东西

工作人员队列:0,1,2,3,4,5,6,7,8,9

UI主队列:0,2,4,5,6,7,9

迟到的事件被取消。我想我可以做一些临时实验并跳过每个x更新,但是在NSOperationQueue框架中是否有一个机制呢?我试着把

[[NSOperationQueue mainQueue] cancelAllOperations];

在最后的循环之外,没有帮助...

修改

基于Amin答案的一个非常简单的解决方案:

        if (!self.isUiOperationHandled){
            self.uiOperationHandled = YES;
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                if ([self.delegate respondsToSelector:@selector(didFinishWritingOneFrameWithSender:)]){
                    [self.delegate didFinishWritingOneFrameWithSender:self];
                }
                self.uiOperationHandled = NO;
            }];
        }            

1 个答案:

答案 0 :(得分:1)

好吧,队列意味着他们排队了。 ; - )

当计数器改变时,只需设置一个标志。如果未设置标志且计数器的实际值,则仅发送更新通知。清除代表末尾的标志。

当循环完成时,也许你想要发送额外的消息。