在Cocoa中将stdout重定向到NSTextView的最佳方法是什么?

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)


Pet*_*sey 5

我想将stdout重定向到NSTextView.

你自己的stdout?

这也适用于子流程的输出吗?

当然.

什么是实现这一目标的最佳方法?

文件描述符是你的朋友.

创建一个管道(使用NSPipe或管道(2))和dup2将其写入结束STDOUT_FILENO.调用子进程时,不要设置它们的标准输出; 他们会继承你的标准输出,这是你的管道.(您可能需要关闭读端的子,虽然我不知道这是否将是必要的;尝试一下,看看它变成是,你需要使用forkexec,并关闭读取结束.)

使用kevent或NSFileHandle以异步方式从后台管道的读取端读取.当新数据进入时,使用某种编码对其进行解释并将其附加到文本视图的内容中.

如果文本视图位于滚动视图中,则应在追加之前检查滚动位置.如果它结束了,你可能希望在追加后将其跳回到最后.