[英]How to gradually retrieve data from NSTask?
I am working on a GUI (Cocoa) for a command-line tool to make it more accessible to people. 我正在为命令行工具使用GUI(Cocoa),以使人们更容易使用它。 Despite it being a GUI, I would like to display the output to an NSTextView. 尽管它是GUI,但我想将输出显示到NSTextView。 The problem is that the output is large and the analysis the tool carries out can take hours/days. 问题在于输出量很大,该工具执行的分析可能需要数小时/天。
Normally, when working with NSTask and NSPipe, the output is displayed only after the task is completely finished (which can take a long time). 通常,使用NSTask和NSPipe时,仅在任务完全完成(可能需要很长时间)后才显示输出。 What I want to do is split the output up and display it gradually (updating every minute for example). 我要做的是将输出拆分并逐渐显示(例如,每分钟更新一次)。
So far I have placed the processing of the data in a separate thread: 到目前为止,我已经将数据处理放在单独的线程中:
[NSThread detachNewThreadSelector:@selector(processData:) toTarget:self withObject:raxmlHandle];
- (void)processData:(id)sender {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *startString = [results string];
NSString *newString = [[NSString alloc] initWithData:[raxmlHandle readDataToEndOfFile] encoding:NSASCIIStringEncoding];
[results setString:[startString stringByAppendingString:newString]];
[startString release];
[newString release];
[pool release];
}
All this is still a bit of voodoo to me and I am not exactly sure how to deal with this challenge. 这一切对我来说仍然有些巫毒,我不确定如何应对这一挑战。
Do you have any suggestions or recommendations? 您有什么建议或建议吗?
Thanks! 谢谢!
You need to use a notification provided by NSFileHandle
. 您需要使用NSFileHandle
提供的通知。
First, add yourself as an observer to the NSFileHandleReadCompletionNotification
首先,将您自己添加为NSFileHandleReadCompletionNotification
的观察者
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(outputReceived:)
name:NSFileHandleReadCompletionNotification
object:nil];
Then, prepare a task, call readInBackgrounAndNotify of the file handle of the pipe, and launch the task. 然后,准备任务,调用管道的文件句柄的readInBackgrounAndNotify ,然后启动任务。
NSTask*task=[[NSTask alloc] init];
[task setLaunchPath:...];
NSPipe*pipe=[NSPipe pipe];
[task setStandardOutput:pipe];
[task setStandardError:pipe];
// this causes the notification to be fired when the data is available
[[pipe fileHandleForReading] readInBackgroundAndNotify];
[task launch];
Now, to actually receive the data, you need to define a method 现在,要实际接收数据,您需要定义一个方法
-(void)outputReceived:(NSNotification*)notification{
NSFileHandle*fh=[notification object];
// it might be good to check that this file handle is the one you want to read
...
NSData*d=[[aNotification userInfo] objectForKey:@"NSFileHandleNotificationDataItem"];
... do something with data ...
}
You might want to read Notification Programming Topics to understand what is going on. 您可能需要阅读“ 通知编程主题”以了解发生了什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.