Sne*_*ney 5 cocoa subprocess stdout
嗨:我想将stdout重定向到NSTextView.这也适用于子流程的输出吗?什么是实现这一目标的最佳方法?
编辑: 根据Peter Hosey的回答我实施了以下内容.但我没有得到通知.我究竟做错了什么?
NSPipe *pipe = [NSPipe pipe];
NSFileHandle *pipeHandle = [pipe fileHandleForWriting];
dup2(STDOUT_FILENO, [pipeHandle fileDescriptor]);
NSFileHandle *fileHandle = [[NSFileHandle alloc] initWithFileDescriptor:pipeHandle];
[fileHandle acceptConnectionInBackgroundAndNotify];
NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];
[dnc addObserver:self selector:@selector(handleNotification:) name:NSFileHandleConnectionAcceptedNotification object:fileHandle];
Run Code Online (Sandbox Code Playgroud)
小智 12
我当时也想做同样的事情并且发现了这篇文章.阅读本文和Apple的文档之后,我能够弄明白.我在这里包括我的解决方案.在接口中声明"pipe"和"pipeReadHandle".在init方法中,我包含以下代码:
pipe = [NSPipe pipe] ;
pipeReadHandle = [pipe fileHandleForReading] ;
dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stdout)) ;
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(handleNotification:) name: NSFileHandleReadCompletionNotification object: pipeReadHandle] ;
[pipeReadHandle readInBackgroundAndNotify] ;
Run Code Online (Sandbox Code Playgroud)
handleNotification:方法是
[pipeReadHandle readInBackgroundAndNotify] ;
NSString *str = [[NSString alloc] initWithData: [[notification userInfo] objectForKey: NSFileHandleNotificationDataItem] encoding: NSASCIIStringEncoding] ;
// Do whatever you want with str
Run Code Online (Sandbox Code Playgroud)
我想将stdout重定向到NSTextView.
你自己的stdout?
这也适用于子流程的输出吗?
当然.
什么是实现这一目标的最佳方法?
文件描述符是你的朋友.
创建一个管道(使用NSPipe或管道(2))和dup2将其写入结束STDOUT_FILENO.调用子进程时,不要设置它们的标准输出; 他们会继承你的标准输出,这是你的管道.(您可能需要关闭读端的子,虽然我不知道这是否将是必要的;尝试一下,看看它变成是,你需要使用fork和exec,并关闭读取结束.)
使用kevent或NSFileHandle以异步方式从后台管道的读取端读取.当新数据进入时,使用某种编码对其进行解释并将其附加到文本视图的内容中.
如果文本视图位于滚动视图中,则应在追加之前检查滚动位置.如果它结束了,你可能希望在追加后将其跳回到最后.