【问题标题】:Is [NSOperationQueue mainQueue] a serial queue?[NSOperationQueue mainQueue] 是串行队列吗?
【发布时间】:2014-12-01 19:43:48
【问题描述】:

以下方法将一些图像上传到远程服务器。我希望它们彼此独立上传(并行)。

- (void)startUploadProcess {
    for (int i = 0; i < [imageNames count]; i++) {
        NSBlockOperation *blockOp = [NSBlockOperation blockOperationWithBlock:^{
            [GlobalsFuncs uploadImageToServer:[[NSImage alloc] initWithContentsOfURL:[imagePaths objectAtIndex:i]]  forSessionID:[[family SessionID] stringValue]  withFilename:[imageNames objectAtIndex:i]];
        }];

        blockOp.completionBlock = ^{
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                [self afterUploadCompletion:i];
            }];
        };
        [bgQueue addOperation:blockOp];
    }
}

- (void)afterUploadCompletion:(NSInteger)pageNumber {
    NSLog(@"%ld for sessionID : %@", (long)pageNumber, family.SessionID);
    imagesUploaded++;
    [progressIndicator incrementBy:progressDelta];
}

从上面的代码可以看出,我为每个图像添加了对afterUploadCompletion 方法的调用。在该方法中,我递增一个作为类实例变量的整数。我的问题是我的代码是否会导致竞争条件?基本上,我要问的是mainQueue 中的所有内容是否都是连续执行的? 另外,如何使NSOperationQueue *bgQueue 成为并行队列?我希望添加到此队列的块不等待先前的操作完成。

非常感谢您的帮助!

【问题讨论】:

  • 为什么不直接打印它在调试器中支持的并发操作数。输入这个问题可以节省 10 分钟的时间。此外,还有一个方便的在线文档。

标签: objective-c multithreading macos nsoperation nsoperationqueue


【解决方案1】:

按照Apple Documentation[NSOperationQueue mainQueue]以串行方式执行操作:-

[NSOperationQueue mainQueue] 返回的队列在应用程序的主线程上一次执行一项操作。主线程上的操作执行与必须在主线程上执行的其他任务交错执行,例如事件服务和应用程序用户界面的更新。队列在运行循环公共模式中执行这些操作,由 NSRunLoopCommonModes 常量表示。

现在,如果您想以并发或并行方式执行操作。请参考以下示例:-

NSOperationQueue * queue = [[NSOperationQueue alloc] init];
NSOperation * nwOperation = [[yourOper alloc] init];
[queue addOperation:nwOperation];

因此,如果您将多个操作添加到队列中,它们都会在后台线程上并行执行,从而允许您的主线程处理用户界面。队列会根据用户拥有的 CPU 内核数智能调度并行操作的数量,从而有效利用用户的硬件。

编辑:-

有关并发操作的更多信息,请参阅Dave Dribin's blog.

【讨论】:

  • 谢谢,但是如果我希望使用 [[NSOperationQueue alloc] init] 创建的队列也是串行的,该怎么办?将它的 'maxConcurrentOperationCount' 设置为 1 是一个好方法吗?
  • 根据大卫的博客,你可以使用队列来限制并行下载的数量,使用 setMaxConcurrentOperationCount。
【解决方案2】:

是的,主队列始终是串行的。使用[[NSOperationQueue alloc] init] 创建的任何队列都将是并发的,这意味着传递给它的操作将并行运行。

【讨论】:

  • 谢谢,但是如果我希望使用 [[NSOperationQueue alloc] init] 创建的队列也是串行的,该怎么办?将它的 'maxConcurrentOperationCount' 设置为 1 是一个好方法吗?
  • 是的。请记住,您应该在所有操作中使用相同的优先级,以防止并发队列之间的优先级倒置。
猜你喜欢
  • 1970-01-01
  • 2012-05-17
  • 2012-06-12
  • 1970-01-01
  • 2013-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多