如何等待NSOperationQueue在单元测试中完成?
- 我有一个NSOperationQueue称为
logEntryGeneratorQueue
- 我想等到队列上的所有操作完成
如果我使用的问题:
[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。
我已经试过
我试着睡眠,它,因为我以为,意味着每个测试更换runUntilDate永远暂停时,它得到这里。
我的问题
有没有更好的方式来等待NSOperationQueue对主线程完成?如果没有,我怎么能得到这个代码在10.6下工作?
解决方案
我意识到,我的代码是一个永恒的循环,因为我在主线程中调用mergeChangesFromContextDidSaveNotification
,同时也在等待队列主线程上完成。并且由于合并更改在waitUntilAllOperationsAreFinished
之后调用,它从未得到执行。
我认为答案是改变我从哪里运行NSOperationQueues。我不应该运行与主线程上的核心数据的东西涉及的NSOperationQueue。无论如何我不应该因为性能原因在主线上运行这些密集的东西。
我想说的是waitUntilAllOperationsAreFinished
应该从事的10.6预期,无论从什么事线程它叫。由于10.6中的操作队列不再使用运行循环,所以没有阻塞并且没有运行循环。你尝试只是调用waitUntilAllOperationsAreFinished
=
我同意马克斯:-waitUntilAllOperationsAreFinished应该工作。你的队列是否被暂停?
不,原来我试图在主线程上同时运行两个不同的东西。真的很明显,现在我回头看看它... – 2010-09-10 12:21:28
恕我直言,你需要考虑,如果其业务的一个(或全部)使用的主要应用程序线程为载体进展waitUntilAllOperationsAreFinished可能会挂起的可能性。例如:你的nsoperation不是并发的,只有在主线程有机会运行时才使用glkview自动更新循环来进行动画和更新自己的状态,并且只有你的操作完成(并且操作被标记为完成)。但它不能在等待完成这些操作时被阻止。
是的,我确实 - 应用程序只是冻结。甚至在10.6。我真的希望这个工作无论你在哪个线上! – 2010-09-01 16:20:36
Wierd。那么不知道。可能是一个错误或一个隐藏的依赖... – 2010-09-01 16:38:23