#import "PerformSelectorAfterDelayVC.h"
@interface PerformSelectorAfterDelayVC ()
@end
@implementation PerformSelectorAfterDelayVC
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// 方法一
// // 当在子线程执行下面的代码的时候,发现
dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
dispatch_async(globalQueue, ^{
NSLog(@"1");
[self performSelector:@selector(test) withObject:nil afterDelay:2.0];
// [self performSelector:@selector(test) withObject:nil];
NSLog(@"3");
// [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
});
//
// 方法二:
// NSLog(@"1");
// [self performSelector:@selector(test) withObject:nil afterDelay:3.0];
// NSLog(@"3");
}
- (void)test
{
NSLog(@"2");
}
@end
总结:
/*
- (id)performSelector:(SEL)sel {
if (!sel) [self doesNotRecognizeSelector:sel];
return ((id(*)(id, SEL))objc_msgSend)(self, sel);
}
- (id)performSelector:(SEL)sel withObject:(id)obj {
if (!sel) [self doesNotRecognizeSelector:sel];
return ((id(*)(id, SEL, id))objc_msgSend)(self, sel, obj);
}
说明performSelector:withObject是发送的objc_msgSend的消息,说明[self performSelector:@selector(test) withObject:nil];等价于[self test];但是
如果换为performSelector:withObject:afterDelay:在子线程中就不执行了,但是如果放在主线程的话,performSelector:withObject:afterDelay:就可以执行,那是因为该方法是在NSRunLoop中定义的,说明afterDelay是跟runLoop有关的.参数afterDelay:说明该方法是将定时器添加到RunLoop中,比如几秒之后开始做事情的定时器放到RunLoop中,Runloop在唤响之后才会处理定时器.所以该代码有效的前提是,有RunLoop,在主线程中有Runloop所以这句代码好使,但是如果在子线程默认情况下,没有runloop,意味着定时器无法工作,除非在子线程中启动runloop之后定时器才可以工作.
*/
第二个关于RunLoop中线程的代码
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
NSThread *thread = [[NSThread alloc]initWithBlock:^{
NSLog(@"1");
// [[NSRunLoop currentRunLoop]addPort:[[NSPort alloc]init] forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop]runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
NSLog(@"END");
}];
[thread start];
[self performSelector:@selector(test) onThread:thread withObject:nil waitUntilDone:YES];
}
- (void)test
{
NSLog(@"2");
CFRunLoopStop(CFRunLoopGetCurrent());
}