我正在使用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",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]; }