3

我用来在我的沙盒应用程序上NSUserUnixTask运行未沙NSTask盒。但是,我的代码挂在对[NSFileHandle readDataToEndOfFile]. 如果我删除这些调用,它会完美运行。如果我用它替换[NSFileHandle readDataToEndOfFile][NSFileHandle availableData]也会挂起。

这是代码:

NSUserUnixTask* unixTask = [[NSUserUnixTask alloc] initWithURL: [NSURL fileURLWithPath: path] error: nil];

// Create error file handle
NSFileHandle* errorFH = [NSFileHandle fileHandleWithStandardError];
[unixTask setStandardError: errorFH];

// Create output file handle
NSFileHandle* outputFH = [NSFileHandle fileHandleWithStandardOutput];
[unixTask setStandardOutput: outputFH];

// Run task with termination handler
[unixTask executeWithArguments: nil completionHandler: ^(NSError* error2) {

    // Save output
    NSString* output = [[NSString alloc] initWithData: [outputFH readDataToEndOfFile] encoding: NSUTF8StringEncoding];
    if ([output length]) { // <-- Execution never reaches this line when the block is called
        NSLog(@"%@", output);
    }

    // Read error 1
    NSString* error1 = [[NSString alloc] initWithData: [errorFH readDataToEndOfFile] encoding: NSUTF8StringEncoding];
    if ([error1 length]) {
        NSLog(@"%@", error1);
    }

    // Read error 2
    if (error2) {
        NSLog(@"%@", error2);
    }
}];

Xcode 的控制台上没有记录任何内容,但是如果我打开 Console.app,我会看到这一行:

Warning: Exception caught during decoding of received reply to message 'executeScript:interpreter:arguments:standardInput:standardOutput:standardError::', dropping incoming message and calling failure block.

Exception: *** -[NSConcreteFileHandle readDataOfLength:]: Bad file descriptor

嗯,我该如何解决这个问题?在我将我的应用程序沙盒化之前,我将NSPipe其与 结合使用NSTask并且一切正常,但现在NSUserUnixTask需要使用NSFileHandle代替,我认为我的问题仅仅是因为我没有正确使用它。但我仍然不知道我做错了什么。

4

1 回答 1

2

在我看来,您必须NSPipeNSUserUnixTask使用NSTask.

我已经用“/bin/ls”任务对其进行了测试,它产生了预期的输出:

NSPipe *outPipe = [NSPipe pipe];
NSPipe *errPipe = [NSPipe pipe];
NSString *path = @"/bin/ls";
NSUserUnixTask *unixTask = [[NSUserUnixTask alloc] initWithURL: [NSURL fileURLWithPath: path] error: nil];
[unixTask setStandardOutput:[outPipe fileHandleForWriting]];
[unixTask setStandardError:[errPipe fileHandleForWriting]];
[unixTask executeWithArguments:nil completionHandler:^(NSError *error) {
    NSString *output = [[NSString alloc] initWithData: [[outPipe fileHandleForReading] readDataToEndOfFile] encoding: NSUTF8StringEncoding];
    NSLog(@"stdout: %@", output);

    NSString *error1 = [[NSString alloc] initWithData: [[errPipe fileHandleForReading] readDataToEndOfFile] encoding: NSUTF8StringEncoding];
    NSLog(@"stderr: %@", error1);
}];
于 2013-05-19T20:01:32.550 回答