如何在主线程上安全地使用[NSTask waitUntilExit]?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在主线程上安全地使用[NSTask waitUntilExit]?相关的知识,希望对你有一定的参考价值。
我有一个多线程程序,需要同时运行许多可执行文件并等待其结果。
我在[nstask waitUntilExit]
中使用NSOperationQueue
,它在非主线程上运行它(在主线程上运行NSTask
完全不可能)。
我的程序随机崩溃或遇到断言失败,崩溃堆栈总是指向由waitUntilExit
运行的runloop,它执行各种回调和处理程序,包括-IMHO错误-KVO和bindings updating the UI,这导致它们在非主线程上运行(这是probably the problem described by Mike Ash)
我怎样才能安全地使用waitUntilExit
?
这是waitUntilExit
基本上无法使用的问题,还是我需要做一些特殊的事情(除了在主线程上显式调度我的回调),当使用KVO和IB绑定来防止它们在运行waitUntilExit
的错误线程上处理?
正如Mike Ash指出的那样,你无法在随机的runloop上调用waitUntilExit
。它很方便,但不起作用。在计算“这实际上是否方便?”时,你必须包含“不起作用”。
但是,您可以在10.7+中使用terminationHandler
。它不会泵送runloop,因此不应该产生这个问题。您可以使用这些行重新创建waitUntilExit
(未经测试;可能无法编译):
dispatch_group group = dispatch_group_create();
dispatch_group_enter(group);
task.terminationHandler = ^{ dispatch_group_leave(group); };
[task launch];
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
// If not using ARC:
dispatch_release(group);
没有你正在做什么的一般背景很难说...
通常,您无法从非主线程更新接口。因此,如果您在非主线程和更新UI中观察到NSTasks的一些KVO通知,那么您就错了。
在这种情况下,你可以简单地解决问题
-[NSObject performSelectorOnMainThread:];
或者类似的想要更新UI。
但至于我更优雅的解决方案:
- 用maxConcurentOperationsCount = 1(所以FIFO队列)编写分离的NSOperationQueue并编写NSOperation的子类,它将执行NSTask并通过委托方法更新UI。这样,您将控制应用程序中执行任务的数量。 (或者你可以停止所有这些或其他)
- 但对于你的问题的高级解决方案,我认为将编写privileged helper tool。使用这种方法,您将获得两个主要好处:您的NSTask将在分离的进程中执行,并且您将拥有执行任务的root权限。
我希望我的答案涵盖你的问题。
以上是关于如何在主线程上安全地使用[NSTask waitUntilExit]?的主要内容,如果未能解决你的问题,请参考以下文章