使用NSTask:返回输出后应用程序冻结

时间:2009-08-08 23:21:26

标签: objective-c cocoa nsdata 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的二进制文件。

问题是代码运行并返回输出但随后会冻结应用程序。我逐行完成了它,发现这一行是问题所在:

data = [[output fileHandleForReading] readDataToEndOfFile];

此行本身将输出记录到控制台,然后冻结应用程序。我通过删除该行之后的所有其他行来检查这一点,它仍然记录输出并冻结。调试器中没有任何内容,我们将非常感谢有关如何解决此问题的任何建议。

4 个答案:

答案 0 :(得分:2)

看起来你错过了

[proc setStandardOutput:output];

答案 1 :(得分:1)

这个问题的解决方案很简单,

它是一个已知的错误,在执行NSTask之后,所有日志记录都不起作用。它返回一个输出,它只是没有记录它。解决方案是添加以下行:

[task setStandardInput:[NSPipe pipe]];

一切正常:)

答案 2 :(得分:0)

在最后一个sed语句的末尾有一个额外的斜杠。删除后,脚本运行正常。

答案 3 :(得分:0)

应使用[NSPipe pipe](无主)创建

输出,然后使用[proc setStandardOutput:output]将输出设置为标准输出

但是你崩溃的原因是因为你发布了你没有分配,新的或复制的数据。请参阅memory management rules

另外,请参阅Quickies for NSTask以获得此代码的干净实现。