0

我尝试NSTaskNSOperation.

这是我整理的一个非常简单的应用程序来展示这个问题。单击按钮时,将NSOperation排队。它设置一个NSRunLoop, 并调用一个调用NSTask. 这个任务真的很简单——它只启动/bin/sleep两秒钟(当一切正常时,足以很容易地看到微调器)。

该应用程序的工作原理与宣传的一样,但是如果您将 TaskPerformer.m 的第 23 行更改为autorelease, (对不起,我是新海报,所以我无法直接链接)或完全注释掉它(从而泄漏NSTask对象),NSOperation' s 线程永远不会退出。它的主要运行循环似乎阻塞了某些东西。

现在,这里的问题是双重的。首先,我不明白为什么我的线程会阻塞,但此外,如果我为此应用程序打开垃圾收集,同样的行为会表现出来。因为我无法手动释放NSTask,所以无论如何线程都会阻塞。

如果有人能告诉我发生了什么,我将永远感激不尽!

4

2 回答 2

4

我在您发布的示例项目中看到了几个不同的问题。在 TaskPerformer.m 你有:

[task waitUntilExit];
[task launch];

waitUntilExit调用是启动任务后调用的,并且在任务完成之前将简单地阻塞并且什么都不做。如果您只关心等到任务完成,而不关心从中获取输出或其他任何东西,那么您应该能够只调用launch后跟waitUntilExit,而根本不必打扰运行循环。

但是,如果您确实想从任务中获取输出,那么您将想要获取它的standardOutput,默认情况下它应该返回一个NSFileHandle. 然后您可以调用readDataOfLength:or readDataToEndOfFile,当数据可用时,这两者都会阻止并从进程返回数据。

由于这整个事情无论如何都将在后台线程中完成,这些方法阻塞是可以的,但是您不想在主线程上做同样的事情,因为这会锁定用户界面直到任务完成。如果您在主线程上执行此操作,您会想要使用NSFileHandle'sreadInBackgroundAndNotify和朋友。但是,对于后台线程,使用NSRunLoop应该不是真的必要。

于 2010-07-21T15:32:45.470 回答
1

我弄清楚这里发生了什么。原来我的电话[runLoop run]是设置循环并无限期地运行它。它从未陷入while (!done)循环。事实证明,在调用 之后run, anNSRunLoop将一直运行,直到没有更多输入为止。打电话release给我NSTask导致了这种情况,所以(很偶然)我的运行循环退出了。

解决方案是删除[runLoop run]并简单地依赖我自己的while循环。希望这对其他人有帮助!

于 2010-07-22T17:55:18.940 回答