Использование NSTask:приложение зависает после возврата вывода

StackOverflow https://stackoverflow.com/questions/1250123

Вопрос

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

- (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 для фильтрации его в машиночитаемый формат.Просто для проверки я использовал двоичный файл TextEdit.app для Mac OS X.

Проблема в том, что код запускается и возвращает выходные данные, но затем зависает приложение.Я просмотрел его построчно и обнаружил, что проблема заключается в следующей строке:

данные = [[выходной fileHandleForReading] readDataToEndOfFile];

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

Это было полезно?

Решение 2

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

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

[task setStandardInput:[NSPipe pipe]];

И все работает нормально :)

Другие советы

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

[proc setStandardOutput:output];

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top