Передача дополнительных данных обработчику вывода NSTask

Мне нужно прочитать вывод NSTask. Код из этого сообщения достигает этого: Как получить вывод NSTask в Cocoa ?. Однако я хочу передать в эту функцию дополнительные данные. Я попытался создать словарь и передать его через селектор, но это не сработало.

NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:completion_, @"a", [outputPipe fileHandleForReading], @"b", nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(readCompleted:) name:NSFileHandleReadToEndOfFileCompletionNotification object:dict];

Любые идеи?


person Nate    schedule 18.02.2015    source источник


Ответы (2)


Во-первых, параметр object: для -addObserver:selector:name:object: — это то, что будет публиковать уведомление. Если уведомление с указанным именем отправлено другим объектом, центр уведомлений не вызывает ваш селектор. Поскольку ваш словарь никогда не будет публиковать NSFileHandleReadToEndOfFileCompletionNotification (поскольку словари не публикуют уведомления), ваш селектор никогда не будет вызываться.

Итак, не передавайте словарь как object. Это не то, что вы думаете. Это не средство передачи информации в метод наблюдения.

Для этого вы можете использовать более современный блочный метод наблюдателя:

__block id observation = [[NSNotificationCenter defaultCenter] addObserverForName:NSFileHandleReadToEndOfFileCompletionNotification
                                                                           object:[outputPipe fileHandleForReading]
                                                                            queue:nil
                                                                       usingBlock:^(NSNotification *note) {
                                                                           // Do whatever you want to do in response to the notification here.
                                                                           // You can access the completion_ variable directly.
                                                                           [[NSNotificationCenter defaultCenter] removeObserver:observation];
                                                                           observation = nil;
                                                                       }];

Вы должны быть осторожны, чтобы поддерживать объект наблюдения до тех пор, пока не сработает уведомление, а также удалить его и освободить (путем очистки строгой ссылки), как только это произойдет. Я показал это выше.

person Ken Thomases    schedule 18.02.2015

Вот асинхронное решение для получения вывода задачи.

task.standardOutput = [NSPipe pipe];
[[task.standardOutput fileHandleForReading] setReadabilityHandler:^(NSFileHandle *file) {
NSData *data = [file availableData]; // this will read to EOF, so call only once
NSLog(@"Task output! %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);

// if you're collecting the whole output of a task, you may store it on a property
//[self.taskOutput appendData:data];

}];

person Kakashi    schedule 08.09.2016