OS X 10.6 Snow Leopard中NSTask的问题

时间:2009-08-30 15:22:07

标签: cocoa macos osx-snow-leopard nstask

是否有其他人在10.6中看到或听说过NSTask的任何问题?

此代码昨天运行良好,今天无法运行。

NSTask *task = [converter task];
[task waitUntilExit];
NSLog(@"Task did complete");

任务执行它应该执行的操作(我检查了输出并且没问题),但程序将无限期地等待waitUntilExit方法。我有一些使用类似代码的单元测试,它们都已经过去了,但截至昨天,他们已经不再工作了。

5 个答案:

答案 0 :(得分:2)

您需要添加以下魔术线:

[task setStandardInput:[NSPipe pipe]];

答案 1 :(得分:1)

(1)您是否以任何方式处理任务的输出?如果是这样,如果你不读取和输出,输出的缓冲可以阻止沿途处理数据。

(2)你的任务在终止之前是否在stdin上等待EOL?如果是这样,你将需要获取标准输入并明确关闭它。

正如彼得所说,检查ps以查看您的任务是否仍在运行。如果是,请使用sample对其进行抽样以确定其最新效果。

答案 2 :(得分:1)

可能 - 我发现10.6上的一些代码存在问题,这听起来很像你的问题。

我需要以完全异步的方式获取一些网络信息(主要涉及BGP和AS的东西)。对我来说,理想的解决方案是将特殊的DNS TXT记录请求发送到可公开访问的DNS服务器,但Cocoa / Core Foundation不提供用于执行这些奇怪的DNS DNS请求的API。另一种方法是使用shell% whois -h IP 'SPECIAL REQUEST'并从输出中解析出相关信息。这是我可以在几个小时内启动并运行的东西,稍后再回来并提供真正的解决方案。非常hacky,但比1)找到合适的异步DNS库和2)加快其API并可能为其编写包装器要快得多。

因此,我创建了一个分组后台线程的类,然后NSTask启动whois请求。后台线程位于NSRunLoop循环中以处理结果,但每隔约1/10秒检查以查看NSTask是否因某种原因而死亡,或[NSThread isCanceled]等等它还会注册NSApplicationWillTerminateNotification通知,以便在应用程序退出时进行适当的清理。

好吧,从10.6开始......我不能再“快速”退出。在10.5,一切都是玻璃光滑,应用程序立即退出,至少在感知上。在10.6下,退出会导致应用程序“挂起”。调试表明,所有事情都在挂断,试图清理挥之不去的whois NSTask。由于我用这种方式得到的信息都不是对应用程序功能至关重要(这是额外的,很高兴知道一些信息),我只是有点鄙视并且不再尝试将信息作为一个停止间隙解决方案。

调试问题的快速通过显示主应用程序在尝试获取实例NSLock时阻止。有趣的是,如果我不管它,应用程序最终会正常退出 - 从10-20秒到几分钟......在10.5和10.6之间发生了一些变化,这导致代码被放在[NSLock lock] ... [NSLock unlock]块中以便占用很长时间'。我还没有找到正在发生的事情(虽然还不是优先事项)......但其中一件事就是终止背景NSTask如果它仍在运行并且在它之前'等待它完成'可以安全地摆脱像NSPipe

这样的东西

DUP :这可能是一个愚蠢的答案......我的第一个似乎已经消失了?

答案 3 :(得分:0)

检查ps,top或Activity Monitor。确保您的流程已退出。

答案 4 :(得分:0)

不确定这是否有帮助,但您可以尝试在单独的线程上进行等待:

[NSThread detachNewThreadSelector: @selector(foo) toTarget: self withObject: task];

...

- (void) foo: (NSTask *) task {
  [task launch];
  [task waitUntilExit];
  ...

我有一个问题,当任务完成时我没有得到NSNotification,并修复了它。显然,在10.6 ...

下的NSTask实现中存在一些错误