到目前为止,我有这个代码,目标是对我的NSTask的某些输出采取行动。本质上它(我的NSTask)是一个程序,随着时间的推移将字符串输出到控制台。我希望能够在控制台上显示某个字符串时,在我的cocoa Objective-C应用程序中调用一个方法。我的想法是将控制台输出传递给我的应用程序,该应用程序检查传递的字符串是否需要执行操作。
NSPipe *pipe = [NSPipe pipe];
NSFileHandle *file = pipe.fileHandleForReading;
self.task = [[NSTask alloc] init];
[self.task setStandardOutput: pipe];
[self.task setStandardError: [self.task standardOutput]];
self.task.launchPath = @"/usr/local/bin/taskThing";
self.task.arguments = @[@"taskArg"];
[self.task launch];
NSMutableData *data = [NSMutableData dataWithCapacity:512];
while ([self.task isRunning]) {
[data appendData:[file availableData]];
}
[file closeFile];
NSString *taskOut = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"task returned: %@ END", taskOut);
这基本上“崩溃”了应用程序,因为while循环导致它只是继续阅读,直到我杀死NSTasks进程。当我确定终止进程时,将记录任务记录的所有记录输出。所以它有点工作,我希望能够做的是在它们出现时对任务输出进行操作,任务将继续运行,所以我无法等待它在接收管道数据之前停止。有什么想法吗?
PS。我刚刚看到提到waitForDataInBackgroundAndNotify
,希望这有帮助,也可以看一下。
答案 0 :(得分:0)
我更多地关注waitForDataInBackgroundAndNotify
。
在启动任务后的上述代码中,我删除了所有后续行,并替换为通知Observer
NSPipe *pipe = [NSPipe pipe];
NSFileHandle *file = pipe.fileHandleForReading;
self.task = [[NSTask alloc] init];
[self.task setStandardOutput: pipe];
[self.task setStandardError: [self.task standardOutput]];
self.task.launchPath = @"/usr/local/bin/taskThing";
self.task.arguments = @[@"taskArg"];
[self.task launch];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(outData:)
name:NSFileHandleDataAvailableNotification object:initialOutputFile];
[file waitForDataInBackgroundAndNotify];
在一种新方法中; " outData:"
- (void)outData:(NSNotification *)notification {
NSFileHandle *outputFile = (NSFileHandle *) [notification object];
NSData *data = [outputFile availableData];
if([data length]) {
NSString *temp = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"Here: %@", temp);
}
[outputFile waitForDataInBackgroundAndNotify];
}
这完全基于此question