1

问题

  • 我有一个名为 NSOperationQueuelogEntryGeneratorQueue
  • 我想等到队列上的所有操作都完成

如果我使用:

[logEntryGeneratorQueue waitUntilAllOperationsAreFinished];

如果添加到队列的线程本身在后台,它工作正常。

但是,如果我通过单元测试运行此代码,它将在主线程上运行。所以我想出了这个“解决方案”,我真的不喜欢:

if ([NSThread isMainThread]) {
    while ([[logEntryGeneratorQueue operations] count] > 0) {
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
    }
} else {
    [logEntryGeneratorQueue waitUntilAllOperationsAreFinished];
}

这总是不太理想,但在 10.5 上一直运行良好。但是,现在我已经将我的项目升级为使用 10.6 SDK,这会中断。

在一项测试中,它实际上在完成之前退出了测试。我不知道为什么 - 我认为这与 NSOperationQueues 在 10.6 中的工作方式不同有关 - 他们现在使用 GCD。

我试过的

我尝试用 sleep 替换 runUntilDate,正如我所想的,这意味着每次测试到这里时都会永远暂停。

我的问题

有没有更好的方法来等待 NSOperationQueue 在主线程上完成?如果没有,我怎样才能让这个代码在 10.6 下工作?

4

4 回答 4

2

解决方案

我意识到我的代码处于一个永恒循环中,因为我mergeChangesFromContextDidSaveNotification在主线程上调用,同时也在等待队列在主线程上完成。并且由于在之后调用了合并更改waitUntilAllOperationsAreFinished,因此它从未被执行。

我认为答案是改变我从哪里运行 NSOperationQueues。我不应该在主线程上运行处理核心数据的 NSOperationQueue。无论如何,出于性能原因,我不应该在主线程上运行这种密集的东西。

于 2010-09-10T12:15:45.133 回答
1

我同意 Max:-waitUntilAllOperationsAreFinished 应该可以工作。您的队列是否已暂停?

于 2010-09-01T16:53:25.197 回答
1

我想说这waitUntilAllOperationsAreFinished应该在 10.6 上按预期工作,无论它是从哪个线程调用的。由于 10.6 中的操作队列不再使用运行循环,因此不阻塞并让循环运行是没有意义的。你试过打电话吗waitUntilAllOperationsAreFinished=

于 2010-09-01T15:58:41.003 回答
0

恕我直言,您需要考虑 waitUntilAllOperationsAreFinished 如果其中一个(或所有)操作正在使用主应用程序线程作为载体进行,则可能会挂起。示例:您的 nsoperation 不是并发的,并且使用 glkview 自动更新循环进行动画和更新自己的状态,并且您的操作仅在主线程有机会工作时才完成(并且操作被标记为已完成)。但它不能,因为它在等待完成这些操作时被阻塞。

于 2011-12-30T22:52:50.917 回答