我在运行一组NSOperations(最大并发设置为1)的主线程上有一个NSOperationQueue,我希望能够在任何时候取消时间。当我按下一个按钮时,我告诉队列取消所有操作并等待直到完成。这应该挂起主线程,直到操作队列为空,但是它无限期地挂起我的主线程。主线程无限期挂起,等待NSOperationQueue操作取消[Only on Device!]
这里是我用来阻止它的代码:
...
[myQueue cancelAllOperations];
[myQueue waitUntilAllOperationsAreFinished];
return YES; // This line never gets called
注:我需要使用waitUntilAllOperationsAreFinished
作为进一步处理要求队列为空。
奇怪的是这只发生在设备上。在模拟器中运行时,按预期工作。
我看过断点,我可以按照当前正在运行的操作,直到它完成。它会检测[self isCancelled],停止正在执行的操作并将其拖动到main
方法的末尾。我可以看到操作中没有任何操作导致它挂起,并且通过取消所有操作,其他任何操作都不应启动,并且队列应该结束。我通过添加断点来检查并且其他操作都没有开始。
这是怎么发生的?
奇怪的是,这是发生在非并发操作,不会在主线程上进行任何调用。不过,我有一个并发操作,在异步调用之间的主线程上执行某些操作,我认为这会被阻止!我不明白为什么这种方法可用,如果它可能导致这些问题。除非它的意思是在另一个不是主线程的线程上调用!?我试图取消我的应用程序终止操作,当它挂起时,由于终止时间而导致崩溃报告。相当棘手的一个!有什么建议么?感谢您的回答! – 2009-12-16 03:05:58
我处理过的一种方法是取消所有会触发主线程的后台进程,然后调用-cancelAllOperations。在任何将在我的操作中的主线程上执行选择器的代码之前,我会添加一个isCancelled检查,如果该检查为true,那么将退出该操作。然后在-cancelAllOperations消息后稍后sleep(),最后调用-waitUntilAllOperationsAreFinished。如果你小心地关闭所有碰到主线程的东西,但是这个,你可以做这个工作。 – 2009-12-16 13:42:05
感谢Brad,这几乎是我克服它的方式。 'cancelAllOperations'然后休眠〜1s(当然!)。我的'NSOperations'检查'isCancelled'很快,在任何可能需要一段时间的事情之前,所以他们应该很快退出。另一个小技巧,我发现我的核心数据保存需要一段时间,我已经使用了一个全球NSCondition,所以我基本上取消,睡眠,等待信号(如果需要)。这完美地保持了主线,像梦一样工作!谢谢你的帮助! – 2009-12-17 10:01:05