嗨:我想将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];
答案 0 :(得分: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] ;
handleNotification:方法是
[pipeReadHandle readInBackgroundAndNotify] ;
NSString *str = [[NSString alloc] initWithData: [[notification userInfo] objectForKey: NSFileHandleNotificationDataItem] encoding: NSASCIIStringEncoding] ;
// Do whatever you want with str
答案 1 :(得分:5)
我想将stdout重定向到NSTextView。
你自己的stdout?
这也可以用于子流程的输出吗?
不确定
实现这一目标的最佳方法是什么?
文件描述符是你的朋友。
创建一个管道(使用NSPipe或pipe(2))和dup2将其写入结束到STDOUT_FILENO
。调用子进程时,不要设置它们的标准输出;他们会继承你的标准输出,这是你的管道。 (你可能想关闭子进程中的读取结束。我不确定这是否有必要;尝试并找出答案。如果结果确实如此,你需要使用{{1} }和fork
,并在两者之间关闭读取结束。)
使用exec
或NSFileHandle异步读取后台管道的读取端。当新数据进入时,使用某种编码对其进行解释并将其附加到文本视图的内容中。
如果文本视图位于滚动视图中,则应在追加之前检查滚动位置。如果它在最后,你可能希望在追加后将其跳回到最后。
答案 2 :(得分:2)
答案 3 :(得分:0)
对于iOS,使用stderr而不是stdout。
NSPipe *pipe = [NSPipe pipe];
pipeHandle = [pipe fileHandleForReading];
dup2([[pipe fileHandleForWriting] fileDescriptor], fileno(stderr));
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(handleNotification:) name: NSFileHandleReadCompletionNotification object: pipeHandle] ;
[pipeHandle readInBackgroundAndNotify] ;
-(void)handleNotification:(NSNotification *)notification{
[pipeHandle readInBackgroundAndNotify] ;
NSString *str = [[NSString alloc] initWithData: [[notification userInfo] objectForKey: NSFileHandleNotificationDataItem] encoding: NSASCIIStringEncoding] ;
}