使用NSTask:返回输出

问题描述:

后的应用程序冻结

您好我有以下代码:使用NSTask:返回输出

- (IBAction)runTask:(id)sender { 
    NSTask *proc; 
    NSPipe *output; 
    NSData *data; 
    NSString *buffer; 

    proc = [[NSTask alloc] init]; 
    output = [[NSPipe alloc] init]; 

    [proc setLaunchPath:@"/bin/sh"]; 
    [proc setArguments:[NSArray arrayWithObjects: @"-c", @"/usr/bin/otool -L /Applications/TextEdit.app/Contents/MacOS/TextEdit | /usr/bin/awk 'NR>1{print $1}' | /usr/bin/sed -e '/@executable_path/d' -e 's/(.*)$//' -e 's/\\/Versions.*$//'", nil]]; 
    [proc launch]; 

    data = [[output fileHandleForReading] readDataToEndOfFile]; 
    buffer = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; 
    NSLog(@"got: %@", buffer); 

    // Release 
    [proc release]; 
    [output release]; 
    [buffer release]; 
    [data release]; 
} 

的代码的目的是有点复杂,它使用otool得到它采用使用二进制那么共享库的列表sed和awk将其过滤为机器可读的格式。为了测试我已经使用了Mac OS X TextEdit.app的二进制文件。

的问题是代码运行和返回的输出,但随后冻结的应用程序。我通过它去逐行,发现这条线是问题:

数据= [[输出fileHandleForReading] readDataToEndOfFile];

该线本身正在记录输出到控制台,然后冷冻该应用。我通过删除该行之后的所有其他行来检查该行,并且它仍然记录输出并冻结。调试器中没有任何东西,并且如何解决这个问题的任何建议将不胜感激。

+1

我复制代码到一个命令行工具,补充丢失的'setStandardOutput:'消息,并运行它。它工作正常,除了在最后过度释放数据。 – 2009-08-09 05:34:35

+0

“我通过删除该行后面的所有其他行来检查此行为...”我建议您改为抽样您的应用程序。见男子1样本。 – 2009-08-09 06:40:03

这个问题的解决办法很简单,

它是一个已知的bug被执行NSTask毕竟日志记录不工作。它正在返回一个输出,它只是不记录它。解决的办法是添加这一行:

[task setStandardInput:[NSPipe pipe]]; 

,一切工作正常:)

它看起来像你缺少一个

[proc setStandardOutput:output]; 
+0

我添加了该行,但现在看起来我根本没有输出。 – indragie 2009-08-09 01:29:04

你在最后SED声明的末尾有一个额外的斜杠。一旦你删除它,脚本工作正常。

+0

我不知道如果我删除了右斜线,我拿出一个在最后SED声明的最后,行是现在这个样子 [PROC setArguments:[NSArray的arrayWithObjects:@“ - C”,@ “在/ usr/bin中/ otool -L /Applications/TextEdit.app/Contents/MacOS/TextEdit |在/ usr /斌/的awk 'NR> 1 {打印$ 1}' |在/ usr/bin中/用sed -e“/ @ executable_path/d'-e's /(.*)$//'-e's/\\/Versions。* $ /'“,nil]]; 但我得到这个错误: 的sed:1:“S/\ /版本* $/\ N”:替代模式 – indragie 2009-08-09 02:36:46

+0

哦,还有,我不认为它与命令本身的问题里面转义换行符,我尝试了一个非常简单的“ls/Volumes”,发生同样的事情,输出被返回,但应用程序冻结。我按照上一张海报的建议在setStandardOutput行中添加了内容,虽然解决了冻结问题,但不再有任何输出。 谢谢 – indragie 2009-08-09 02:39:38

+0

PCWiz:啊,我在尝试命令之前忘记了避开反斜杠,并没有真正阅读它以查看最后一个模式应该结束的位置。最后的斜线属于那里。抱歉。 – 2009-08-09 02:59:17

输出应当与[NSPipe管(无主的),然后输出应该被设置为与[PROC setStandardOutput:输出]标准输出被创建

但你是崩溃的原因是因为你释放数据,其你没有拨出,新的或复制。请参阅memory management rules

而且,看到Quickies for NSTask一个干净的执行这段代码。