在 Cocoa 中将 stdout 重定向到 NSTextView 的最佳方法是什么?
你好:我想将标准输出重定向到 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];
Hi: I want to redirect stdout to a NSTextView. Could this also work with outputs of subprocesses? What might be the best way to achieve this?
EDIT:
According to Peter Hosey answer I implemented the following. But I do not get a notification. What am I doing wrong?
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];
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我想做同样的事情并发现了这篇文章。在阅读了这篇文章和苹果的文档后我才明白了这一点。我在这里包括我的解决方案。 “pipe”和“pipeReadHandle”在接口中声明。在 init 方法中,我包含以下代码:
handleNotification:方法是
I was looking to do the same thing and came across this post. I was able to figure it out after reading this and Apple's documentation. I'm including my solution here. "pipe" and "pipeReadHandle" are declared in the interface. In the init method I included the following code:
The handleNotification: method is
你自己的标准输出?
当然。
文件描述符是你的朋友。
创建管道(使用 NSPipe 或 pipe (2)) 和 dup2 将其写入结束到
STDOUT_FILENO
。调用子进程时,不要设置其标准输出;他们将继承你的标准输出,即你的管道。 (不过,您可能想关闭子进程中的读取端。我不确定这是否有必要;尝试一下并找出答案。如果确实如此,您将需要使用fork
和exec
,并在其间关闭读取端。)使用
kevent
或 NSFileHandle 在后台从管道的读取端异步读取。当新数据进入时,使用某种编码对其进行解释并将其附加到文本视图的内容中。如果文本视图位于滚动视图中,则应在附加到文本视图之前检查滚动位置。如果它在末尾,您可能希望在附加后将其跳回末尾。
Your own stdout?
Sure.
File descriptors are your friend here.
Create a pipe (using either NSPipe or pipe(2)) and dup2 its write end onto
STDOUT_FILENO
. When invoking subprocesses, don't set their stdout; they'll inherit your stdout, which is your pipe. (You may want to close the read end in the subprocess, though. I'm not sure whether this will be necessary; try it and find out. If it does turn out to be, you'll need to usefork
andexec
, and close the read end in between.)Read from the read end of the pipe in the background asynchronously, using either
kevent
or NSFileHandle. When new data comes in, interpret it using some encoding and append it to the contents of the text view.If the text view is in a scroll view, you should check the scroll position before appending to it. If it was at the end, you'll probably want to jump it back to the end after appending.
看看PseudoTTY.app!
Have a look at PseudoTTY.app!
对于 iOS,请使用 stderr 而不是 stdout。
For iOS use stderr instead of stdout.