2011-02-28 1 views
2

Итак, у меня есть NSTask для запуска скрипта, который генерирует список чего-то, в txt, который я читал. Но если я использую свой текущий код (см. Ниже), предупреждение появляется до завершения NSTask, что приводит к пустому предупреждению. Я пробовал waitUntilExit, но это делает кнопку, которая вызывает это действие, но пользовательский интерфейс не блокирует себя.NSTask waitUntilExit приложение для зависания на jailbroken iOS

- (void) runSupported { 
    stask = [[NSTask alloc] init]; 
    [stask setLaunchPath:@"/bin/bash"]; 
    NSString *script; 
    script = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/apps.sh"]; 
    NSArray *sargs = [NSArray arrayWithObjects:script, @"-txt", nil]; 
    [stask setArguments: sargs]; 
    [stask launch]; 

    NSString *apps; 
    apps = [NSString stringWithContentsOfFile:@"/var/mobile/supported.txt" encoding:NSUTF8StringEncoding error:nil]; 
    NSFileManager *fm = [NSFileManager defaultManager]; 
    if ([fm fileExistsAtPath:apps]) { 
     UIAlertView *supported = [[UIAlertView alloc] initWithTitle:@"App List" message:apps delegate:self cancelButtonTitle:@"Ok!" otherButtonTitles:nil]; 
     [supported show]; 
     [supported release]; 
    } else { 
     UIAlertView *supported = [[UIAlertView alloc] initWithTitle:@"App List" message:@"Error generating list." delegate:self cancelButtonTitle:@"Ok!" otherButtonTitles:nil]; 
     [supported show]; 
     [supported release]; 
    } 
} 

Любая идея, как бы я закончил NSTask до вызова предупреждения? Благодарю.

Edit: Код с NSNotification:

-(IBAction) supported { 
    stask = [[NSTask alloc] init]; 
    [stask setLaunchPath:@"/bin/bash"]; 
    NSString *script; 
    script = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/apps.sh"]; 
    NSArray *sargs = [NSArray arrayWithObjects:script, @"-txt", nil]; 
    [stask setArguments: sargs]; 
    [[NSNotificationCenter defaultCenter] addObserver: self 
              selector: @selector(taskEnded:) 
               name: NSTaskDidTerminateNotification 
               object: nil]; 
    [stask launch]; 
} 

- (void)taskEnded:(NSNotification *)notification { 
    if (stask == [[notification object] terminationStatus]) { 
     NSString *apps; 
     apps = [NSString stringWithContentsOfFile:@"/var/mobile/supported.txt" encoding:NSUTF8StringEncoding error:nil]; 
     NSFileManager *fm = [NSFileManager defaultManager]; 
     if ([fm fileExistsAtPath:apps]) { 
      UIAlertView *supported = [[UIAlertView alloc] initWithTitle:@"Apps" message:apps delegate:self cancelButtonTitle:@"Ok!" otherButtonTitles:nil]; 
      [supported show]; 
      [supported release]; 
     } else { 
      UIAlertView *supported = [[UIAlertView alloc] initWithTitle:@"Apps" message:@"Error generating list." delegate:self cancelButtonTitle:@"Ok!" otherButtonTitles:nil]; 
      [supported show]; 
      [supported release]; 
     } 
    } else { 
     NSLog(@"Task failed."); 
    } 
} 
+0

Что с копирайтом вы нацеливание, iPhone или Mac NSTask не допускается прошивкой, и UIAlertView не существует на Mac – Guillaume

+0

IOS джейлбрейкиутый, чтобы быть точным – Mitochondria

ответ

1

Не используйте waitUntilExit.

Проблема заключается в том, как сделать что-то после завершения задачи, не блокируя пользовательский интерфейс (или замораживая эту кнопку). Решение, как и для всех подобных проблем, должно быть отправлено :, когда задача завершается, и продолжайте дальше (покажите предупреждение) в ответ на это уведомление.

Уведомление в этом случае является NSNotification под названием NSTaskDidTerminateNotification. Когда задача выходит, по какой-либо причине объект NSTask отправит это уведомление в NSNotificationCenter по умолчанию. Вы можете задать задачу, каков ее статус завершения, чтобы определить, удалось ли это, не удалось или произошел сбой.

См. Также: Notification Programming Topics.

0

Не используйте waitUntilExit в вашей основной теме. Это заблокирует ваш пользовательский интерфейс и заморозит ваше приложение.

Вы должны подписаться на уведомление NSTaskDidTerminateNotification, который размещен, когда задача остановил выполнение:

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(taskDidTerminate:) 
              name:NSTaskDidTerminateNotification 
              object:nil]; 

Обратите внимание, что уведомление может быть размещена, если задача завершена нормально, или в результате terminate сообщение:

- (void) taskDidTerminate:(NSNotification *)notification { 
    if (YOUR_TASK_SUCCESS_VALUE == [[notification object] terminationStatus]) { 
     NSLog(@"Task succeeded."); 
     // Here you can add your checks on the creation on the files and user alerts confirmation 
    } else { 
     NSLog(@"Task failed."); 
    } 
} 

не забудьте отменить подписку на уведомления; в зависимости от того, где вы подписаться на уведомление, хорошее место будет в вашем методе dealloc:

[[NSNotificationCenter defaultCenter] removeObserver:self]; 

Update: Вы ожидаете, что-то, что задокументировано на Mac работать так же на IOS, где это не документировано. Не удивительно, что это не работает.

Вы пытались выполнить задачу - и использовать метод waitUntilExit - в фоновом потоке? Если вам повезет, и он работает, не забудьте вернуться к основной теме, показывая ваш UIAlert.

+0

Я только что отредактировали О.П. с кодом NSNotification, который я использовал (я пытаюсь). Я вижу, что сценарий запускается в консоли отладки, но в приложении не появляется предупреждение. Кажется, что это не вызов 'taskEnded:' – Mitochondria

0

Посмотрите на AMShellWrapper, который основан на примере кода модели Moriarity от Apple.

«Соедините свои собственные методы с stdout и stderr, получите уведомление о завершении процесса и многое другое."

См:?... http://www.cocoadev.com/index.pl?NSTask

+0

Это не подходит для iOS, к сожалению , – Mitochondria