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

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

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

Есть идеи?

2 ответа

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

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

}];

Во-первых, 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;
                                                                       }];

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

Другие вопросы по тегам