objective-c - NSTask 阻塞主线程

标签 objective-c cocoa nstask

我正在使用 NSTask,但是当我启动任务时它会阻塞主线程(因此我无法更新它)直到任务结束。这是我的代码:

NSString *hostsforping = @"google.es";
    pingdata = [[NSTask alloc] init];
    [pingdata setLaunchPath: @"/sbin/ping"];

    NSArray *pingargs;
    pingargs = [NSArray arrayWithObjects: @"-c 5", hostsforping, nil];
    [pingdata setArguments: pingargs];

    NSPipe *pingpipe;
    pingpipe = [NSPipe pipe];
    [pingdata setStandardOutput: pingpipe];

    NSFileHandle *pingfile;
    pingfile = [pingpipe fileHandleForReading];

    [pingdata launch];

    NSData *pingdata1;
    pingdata1 = [pingfile readDataToEndOfFile];

    NSString *pingstring;
    pingstring = [[NSString alloc] initWithData: pingdata1 encoding: NSUTF8StringEncoding];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(taskDidTerminate:)
                                                 name:NSTaskDidTerminateNotification
                                               object:nil];
}
- (void) taskDidTerminate:(NSNotification *)notification {
    NSLog(@"end");
}

我一直在读到 -waitUntilExit 确实会阻塞主线程,但我没有使用它,所以我不知道我做错了什么。

最佳答案

在后台线程上运行任务,readDataToEndOfFile 阻塞主线程。

// Offload the method onto a background thread, could also use Grand Central Dispatch   
[self performSelectorInBackground:@selector(startTask) withObject:nil];


- (void)startTask {
    NSString *hostsforping = @"google.es";
    NSTask *pingdata = [[NSTask alloc] init];
    [pingdata setLaunchPath: @"/sbin/ping"];

    NSArray *pingargs;
    pingargs = [NSArray arrayWithObjects: @"-c 5", hostsforping, nil];
    [pingdata setArguments: pingargs];

    NSPipe *pingpipe;
    pingpipe = [NSPipe pipe];
    [pingdata setStandardOutput: pingpipe];

    NSFileHandle *pingfile;
    pingfile = [pingpipe fileHandleForReading];

    [pingdata launch];

    NSData *pingdata1;    
    pingdata1 = [pingfile readDataToEndOfFile];

    NSString *pingstring;
    pingstring = [[NSString alloc] initWithData: pingdata1 encoding: NSUTF8StringEncoding];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(taskDidTerminate:)
                                                 name:NSTaskDidTerminateNotification
                                               object:nil];
}

- (void) taskDidTerminate:(NSNotification *)notification {
    // Note this is called from the background thread, don't update the UI here
    NSLog(@"end");

    // Call updateUI method on main thread to update the user interface
    [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO];
}

关于objective-c - NSTask 阻塞主线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7676508/

相关文章:

objective-c - OSX 中使用 AudioQueue 的 AEC(回声消除支持)

objective-c - NSTableView 中的鼠标悬停

objective-c - 将 NSControl 添加到 IKImageBrowserCell

swift - 在 swift 中运行终端命令不起作用

objective-c - 如何使用 NSTask 获得类似于 Tail -f 的内容

objective-c - 保持 NSTask session 运行 - Cocoa

ios - 更新自定义嵌套 plist 中的值

objective-c - unsafe_unretained 与弱 : crash during setDelegate

iphone 开发 : how to put a UIView over UITableView

Swift NSCollectionView 从下到上的流程