Использование NSTask: приложение зависает после возврата вывода
Привет у меня есть следующий код:
- (IBAction)runTask:(id)sender {
NSTask *proc;
NSPipe *output;
NSData *data;
NSString *buffer;
proc = [[NSTask alloc] init];
output = [[NSPipe alloc] init];
[proc setLaunchPath:@"/bin/sh"];
[proc setArguments:[NSArray arrayWithObjects: @"-c", @"/usr/bin/otool -L /Applications/TextEdit.app/Contents/MacOS/TextEdit | /usr/bin/awk 'NR>1{print $1}' | /usr/bin/sed -e '/@executable_path/d' -e 's/(.*)$//' -e 's/\\/Versions.*$//'", nil]];
[proc launch];
data = [[output fileHandleForReading] readDataToEndOfFile];
buffer = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(@"got: %@", buffer);
// Release
[proc release];
[output release];
[buffer release];
[data release];
}
Назначение кодов довольно сложное, оно использует otool для получения списка общих библиотек, используемых двоичным файлом, затем использует sed и awk для фильтрации его в машиночитаемый формат. Просто для тестирования я использовал бинарный файл Mac OS X TextEdit.app.
Проблема в том, что код запускается и возвращает выходные данные, но затем останавливает приложение. Я прошел по этой строке построчно и обнаружил, что эта строка является проблемой:
data = [[output fileHandleForReading] readDataToEndOfFile];
Эта строка сама записывает вывод на консоль, а затем останавливает приложение. Я проверил это, удалив все остальные строки после этой строки, и он все еще регистрирует вывод и зависает. В отладчике нет ничего, и любые предложения о том, как решить эту проблему, будут с благодарностью.
4 ответа
Решение этой проблемы было простым,
Это известная ошибка, что после выполнения NSTask все журналы не работают. Он возвращает вывод, его просто не регистрируют. Решением было добавить эту строку:
[task setStandardInput:[NSPipe pipe]];
И все отлично работает:)
У вас есть лишняя косая черта в конце последнего оператора sed. Как только вы удалите его, скрипт работает нормально.
Вывод должен быть создан с помощью [NSPipe pipe] (не принадлежит), а затем вывод должен быть установлен как стандартный вывод с помощью [proc setStandardOutput: output]
Но причина сбоя в том, что вы выпускаете данные, которые вы не распределили, не создали или не скопировали. Смотрите правила управления памятью.
Также посмотрите Quickies для NSTask для хорошей чистой реализации этого кода.