Использование NSTask: приложение зависает после возврата вывода - PullRequest
1 голос
/ 09 августа 2009

Привет, у меня есть следующий код:

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

2 голосов
/ 09 августа 2009

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

[proc setStandardOutput:output];
1 голос
/ 17 августа 2009

Решение этой проблемы было простым,

Известная ошибка, что после выполнения NSTask все журналы не работают. Он возвращает вывод, его просто не регистрируют. Решением было добавить эту строку:

[task setStandardInput:[NSPipe pipe]];

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

0 голосов
/ 09 августа 2009

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

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

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

0 голосов
/ 09 августа 2009

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

...