- (void)viewDidLoad {
[super viewDidLoad];
NSThread *thread = [[NSThread alloc] initWithBlock:^{
NSLog(@"1");
}];
[thread start];
[self performSelector:@selector(test) onThread:thread withObject:nil waitUntilDone:YES];
}
- (void)test {
NSLog(@"2");
}
打印结果:
1
然后崩溃
错误信息是:
Terminating app due to uncaught exception ‘NSDestinationInvalidException’, reason: ‘*** -[ViewController performSelector:onThread:withObject:waitUntilDone:modes:]: target thread exited while waiting for the perform’
这是因为
- test 方法是放在 thread 线程中执行的;
- 当 程序执行到
[thread start]
方法时,initWithBlock
中的 内容已经执行完毕,thread 线程就销毁了。 - 所以当 执行 test 方法时, 因 thread 线程已经被销毁。自然就崩溃了。
可以添加 runloop 来解决此问题。
NSThread *thread = [[NSThread alloc] initWithBlock:^{
NSLog(@"1");
[[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}];
[thread start];
[self performSelector:@selector(test) onThread:thread withObject:nil waitUntilDone:YES];
如果代码改成 后 执行 [thread start ] 会发生什么 ?
- (void)getNSThreadFirst {
NSLog(@"123");
NSThread *thread = [[NSThread alloc] initWithBlock:^{
NSLog(@"1");
}];
NSLog(@"456");
[self performSelector:@selector(test) onThread:thread withObject:nil waitUntilDone:YES];
NSLog(@"789");
[thread start];
NSLog(@"098");
}
执行结果:
这是因为 相互等待,因为 waitUntilDone = yes 。
把 waitUntilDone 改成 No.
- (void)getNSThreadFirst {
NSLog(@"123");
NSThread *thread = [[NSThread alloc] initWithBlock:^{
NSLog(@"1");
}];
NSLog(@"456");
[self performSelector:@selector(test) onThread:thread withObject:nil waitUntilDone:NO];
NSLog(@"789");
[thread start];
NSLog(@"098");
}
执行结果: