如何等待NSOperationQueue在单元测试中完成?

问题描述:

如何等待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 =

+0

是的,我确实 - 应用程序只是冻结。甚至在10.6。我真的希望这个工作无论你在哪个线上! – 2010-09-01 16:20:36

+0

Wierd。那么不知道。可能是一个错误或一个隐藏的依赖... – 2010-09-01 16:38:23

我同意马克斯:-waitUntilAllOperationsAreFinished应该工作。你的队列是否被暂停?

+0

不,原来我试图在主线程上同时运行两个不同的东西。真的很明显,现在我回头看看它... – 2010-09-10 12:21:28

恕我直言,你需要考虑,如果其业务的一个(或全部)使用的主要应用程序线程为载体进展waitUntilAllOperationsAreFinished可能会挂起的可能性。例如:你的nsoperation不是并发的,只有在主线程有机会运行时才使用glkview自动更新循环来进行动画和更新自己的状态,并且只有你的操作完成(并且操作被标记为完成)。但它不能在等待完成这些操作时被阻止。