Каков наилучший способ перенаправить стандартный вывод в NSTextView в Какао? - PullRequest
5 голосов
/ 09 марта 2010

Привет: я хочу перенаправить стандартный вывод в NSTextView. Может ли это также работать с выходами подпроцессов? Какой может быть лучший способ добиться этого?

EDIT: Согласно ответу Питера Хоси, я реализовал следующее. Но я не получаю уведомления. Что я делаю не так?

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];

Ответы [ 4 ]

12 голосов
/ 07 апреля 2010

Я хотел сделать то же самое и наткнулся на этот пост. Я смог понять это после прочтения этого и документации 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] ;

дескрипторNotification: метод

[pipeReadHandle readInBackgroundAndNotify] ;
NSString *str = [[NSString alloc] initWithData: [[notification userInfo] objectForKey: NSFileHandleNotificationDataItem] encoding: NSASCIIStringEncoding] ;
// Do whatever you want with str 
5 голосов
/ 09 марта 2010

Я хочу перенаправить стандартный вывод в NSTextView.

Ваш собственный стандартный вывод?

Может ли это также работать с выходами подпроцессов?

Конечно.

Какой может быть лучший способ достичь этого?

Файловые дескрипторы - ваш друг здесь.

Создайте канал (используя NSPipe или pipe (2) ) и dup2 его конец записи на STDOUT_FILENO. При вызове подпроцессов не устанавливайте их стандартный вывод; они унаследуют ваш стандартный вывод, который является вашей трубкой. (Возможно, вы захотите закрыть конец чтения в подпроцессе. Я не уверен, понадобится ли это, попробуйте и выясните. Если это так, вам нужно будет использовать fork и exec и закройте конец чтения между ними.)

Асинхронно читать с конца чтения канала в фоновом режиме, используя kevent или NSFileHandle. Когда поступают новые данные, интерпретируйте их, используя некоторую кодировку, и добавьте их к содержимому текстового представления.

Если текстовое представление находится в режиме прокрутки, вы должны проверить положение прокрутки, прежде чем добавлять к нему. Если это было в конце, вы, вероятно, захотите вернуться к концу после добавления.

2 голосов
/ 22 сентября 2010

Посмотрите на PseudoTTY.app !

0 голосов
/ 12 июля 2016

Для 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] ;

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...