Привет: Я хочу перенаправить 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];
Я хотел сделать то же самое и наткнулся на этот пост. Я смог понять это, прочитав это и документацию Apple. Я включаю здесь свое решение."pipe" и "pipeReadHandle" объявлены в интерфейсе. В метод инициализации я включил следующий код:
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
Я хочу перенаправить стандартный вывод в NSTextView.
Ваш собственный стандартный вывод?
Может ли это также работать с выходными данными подпроцессов?
Конечно.
Как лучше всего добиться этого?
Дескрипторы файлов - ваши друзья.
Создайте канал (используя NSPipe или pipe (2) ) и dup2 его конец записи на STDOUT_FILENO
. При вызове подпроцессов не устанавливайте их стандартный вывод; они унаследуют ваш стандартный вывод, то есть вашу трубу. (Однако вы можете захотеть закрыть конец чтения в подпроцессе. Я не уверен, будет ли это необходимо; попробуйте и узнайте. Если это действительно так, вам нужно использовать вилку
и exec
, и закройте конец чтения между ними.)
Чтение с конца канала чтения в фоновом режиме асинхронно, используя либо kevent
, либо NSFileHandle. Когда поступают новые данные, интерпретируйте их, используя некоторую кодировку, и добавьте их к содержимому текстового представления.
Если текстовое представление находится в режиме прокрутки, вы должны проверить положение прокрутки перед добавлением к нему. Если это было в конце, вы, вероятно, захотите вернуться к концу после добавления.