繁体   English   中英

越狱的iOS上的NSTask waitUntilExit挂起的应用程序

[英]NSTask waitUntilExit hanging app on jailbroken iOS

因此,我让NSTask运行了一个脚本,该脚本将一些内容列表生成为txt文件,供我读取。 但是,如果我使用当前代码(如下),则在NSTask完成之前会弹出警报,从而导致出现空白警报。 我尝试过waitUntilExit但是这会使调用此操作的按钮冻结,但UI不会自行锁定。

- (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吗? 谢谢。

编辑:带有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."); 
    }
}

不要使用waitUntilExit

问题是任务完成后如何在不阻止UI(或冻结该按钮)的情况下执行某些操作。 对于所有类似问题,解决方案在任务完成时得到通知 ,并响应该通知而继续进行操作(显示警报)。

在这种情况下,该通知是名为NSTaskDidTerminateNotification的NSNotification。 任务退出时,无论出于何种原因,NSTask对象都会在默认的NSNotificationCenter上发布此通知。 您可以询问任务的终止状态是什么,以确定它是成功,失败还是崩溃。

另请参阅: 通知编程主题

不要在主线程上使用waitUntilExit 这将阻止您的UI,并冻结您的应用程序。

您需要订阅通知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];

更新:您希望Mac上记录的某些东西在iOS上也能工作,而iOS上没有记录。 并不奇怪,它不起作用。

您是否尝试过在后台线程中执行任务-并使用waitUntilExit方法? 如果您很幸运并且可以正常工作,请在显示UIAlert时不要忘记切换回主线程。

看看基于Apple的Moriarity示例代码的AMShellWrapper。

“将您自己的方法连接到stdout和stderr,获得有关进程终止的通知等。”

请参阅: http//www.cocoadev.com/index.pl?NSTask

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM