2015-01-27 3 views
0

Это мой первый настоящий проект Cocoa. Я написал функцию, которая принимает NSString как входную, использует NSTask для запуска команды ADB и возвращает вывод терминала в NSString. Код строит отлично, но когда я нажимаю кнопку для запуска этой функции, приложение зависает. Когда я принудительно закрываю, я вижу Thread 1: signal SIGTERM на линии data = [file readDataToEndOfFile];.SIGTERM при возвращении NSString

Функция

NSString* runADBCommand(NSString *cmd) 
{ 
    [[NSTask launchedTaskWithLaunchPath:adbPath 
           arguments:[NSArray arrayWithObjects: cmd, nil]]waitUntilExit]; 

    NSTask *adbDevices = [[NSTask alloc] init]; 
    adbDevices.launchPath = adbPath; 
    NSString* devices = @"devices"; 
    adbDevices.arguments = @[devices]; 

    NSPipe *pipe; 
    pipe = [NSPipe pipe]; 
    [adbDevices setStandardOutput:pipe]; 

    NSFileHandle *file; 
    file = [pipe fileHandleForReading]; 

    NSData *data; 
    data = [file readDataToEndOfFile]; 

    NSString *adbComOutput; 
    adbComOutput = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 

    NSLog(@"\n\n%@", adbComOutput); 
    return adbComOutput; 
} 

Вызов

- (void) getVersion:(id)sender 
{ 
    runADBCommand(@"shell cat /system/build.prop | grep incremental"); 
} 

Я искал ссылки в Интернете, но я не уверен, что искать. Любая помощь приветствуется!

ответ

1

Сообщение signal SIGTERM является следствием того, что вы вынуждены покинуть процесс. Это механизм, с помощью которого выполняется принудительное завершение: сигнал POSIX, в частности SIGTERM, доставляется в целевой процесс и обычно приводит к его завершению.

Поскольку процесс отлаживается, отладчик перехватывает сигнал и сообщает об этом, чтобы вы могли его отлаживать. Конечно, в этом случае вас не интересует отладка получения этого сигнала. (Кстати, вы можете просто нажать кнопку «Стоп» на панели инструментов Xcode, чтобы остановить застрявший процесс без этого побочного эффекта. Вы также можете нажать кнопку «Пауза», чтобы прервать программу, не прерывая ее, чтобы узнать, где она застряла, и исследовать причину.)

Реальный вопрос: почему ваш звонок на -readDataToEndOfFile блокировки навсегда. Причина проста, вы никогда не запускали задачу, которая записывала бы выход, а затем закрывала конец записи в трубе. Вы никогда не звоните [adbDevices launch]. Конечно, вам нужно будет сделать это до, блокируя его выход.

Кроме того, функция runADBCommand(), которую вы отправили, создает объекты двух задач. Первая строка:

[[NSTask launchedTaskWithLaunchPath:adbPath 
          arguments:[NSArray arrayWithObjects: cmd, nil]]waitUntilExit]; 

создает и запускает задачу и ждет ее выхода. Затем функция продолжает создавать совершенно другую задачу для запуска команды devices. Я подозреваю, что это всего лишь остаток экспериментов. Я просто хотел быть уверенным, что вы об этом знаете.

+0

Большое спасибо за это удивительное объяснение! Я даже не понял, что я забыл заявление о запуске. Я положил '[adbDevices launch];' прямо после 'file = [pipe fileHandleForReading];' и он отлично работает! – Thomas

Смежные вопросы