自己的一些测试结论:
Note:对于
performSelector:
操作,如果没有afterDelay:
则会在当前线程立即执行;但是如果加了afterDelay:
,则会被添加到相应线程的RunLoop
中执行。对于performSelector:
如果有onThread:
,那么该处理也会被添加到指定线程的RunLoop
中去执行。对于非主线程的其他线程,默认下是没有RunLoop
的,使用[NSRunLoop currentRunLoop]
会在当前线程创建RunLoop
,但该RunLoop
需要手动run
起来。如果使用NSTimer
或执行performSelector:
将对应任务加入到线程的RunLoop
中,一定要启动对应线程的RunLoop
,即[[NSRunLoop currentRunLoop] run]
。
- (void)viewDidLoad {
[super viewDidLoad];
[self performSelector:@selector(printYogy) withObject:nil];
NSLog(@"_missing");
}
- (void)printYogy {
NSLog(@"yogy....");
}
// 输出为:
// yogy....
// _missing
- (void)viewDidLoad {
[super viewDidLoad];
[self performSelector:@selector(printYogy) withObject:nil :0];
NSLog(@"_missing");
}
- (void)printYogy {
NSLog(@"yogy....");
}
// 输出为:
// _missing
// yogy....
- (void)viewDidLoad {
[super viewDidLoad];
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(printYogy) object:nil];
[thread start];
[self performSelector:@selector(printHaHa) onThread:thread withObject:nil waitUntilDone:NO];
NSLog(@"_missing");
}
- (void)printYogy {
// 如果注释下面两行代码,就不会输出 Haha.... 但会输出 yogy... 说明了,
// performSelector: onThread: 是把操作加到指定线程的 RunLoop 中。且由于 RunLoop 就是在一个线程中执行的,
// 所以当一个线程的 RunLoop 如果 run 起来,当前线程就进入 run,而等待它返回。(目前它一直都没有返回)
[[NSRunLoop currentRunLoop] addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
NSLog(@"yogy....");
}
- (void)printHaHa {
NSLog(@"Haha....");
}
// 输出为:
// Haha....
// _missing
Note:对于
Serial Dispatch Queue
使用waitUntilDone:YES
同样有效。其实,performSelector:
操作都是相对于指定线程的RunLoop
来说的,所以与Dispatch Queue
没有任何联系。这里只是说明了:一个线程可以对自己使用waitUntilDone:YES
。
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
NSLog(@"...queue");
[self performSelector:@selector(printYogy)
onThread:[NSThread currentThread]
withObject:nil
waitUntilDone:YES];
NSLog(@"_missing");
});
[NSThread sleepForTimeInterval:1.0];
NSLog(@"...main");
}
- (void)printYogy {
[NSThread sleepForTimeInterval:2.0];
NSLog(@"yogy....");
}
// 输出为:
// ...main
// ...queue
// yogy....
// _missing
参考资料:
深入理解RunLoop
RunLoop基础元素解析
【iOS程序启动与运转】- RunLoop个人小结
NSTimer和Runloop的关系