Использование 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]];

И все отлично работает:)

Похоже, вам не хватает

[proc setStandardOutput:output];

У вас есть лишняя косая черта в конце последнего оператора sed. Как только вы удалите его, скрипт работает нормально.

Вывод должен быть создан с помощью [NSPipe pipe] (не принадлежит), а затем вывод должен быть установлен как стандартный вывод с помощью [proc setStandardOutput: output]

Но причина сбоя в том, что вы выпускаете данные, которые вы не распределили, не создали или не скопировали. Смотрите правила управления памятью.

Также посмотрите Quickies для NSTask для хорошей чистой реализации этого кода.

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