平时我们想延迟一段代码的运行,最简单的方法就是使用 performSelector afterDelay,但是你有没有发现在子线程中调用这个方法,有时候延时执行的代码并没有走,这是为什么呢?
我们先看一下下面的例子:
我们在.m文件里面加入如下方法
- (void)viewDidLoad {
[super viewDidLoad];
NSThread * thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadRun) object:nil];
[thread start];
}- (void)threadRun
{
[self performSelector:@selector(delayTest) withObject:nil afterDelay:0.2]; //不会调用
[self performSelector:@selector(noDelayTest) withObject:nil]; //会调用
}
- (void)delayTest
{
NSLog(@"this is delayTest");
}
- (void)noDelayTest
{
NSLog(@"this is noDelayTest");
}
我们发现,在0.2秒之后,delayTest方法并没有走,而如果我们没有使用afterDelay的noDelayTest 方法却直接调用了,这是为什么呢?
其实performSelector 方法相当于告诉当前线程去直接去调用noDelayTest方法,noDelayTest方法当然会被调用,
而performSelector afterDelay 相当于 告诉当前线程 用当前线程的定时器去调用delayTest方法,但是我们知道,在子线程中,默认是没有定时器的,所以delayTest方法将没有被调用的机会.
解决办法
使用dispatch_after代替performSelector afterDelay,具体如下
- (void)threadRun
{
//会调用
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 0.2*NSEC_PER_SEC);
dispatch_after(time, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self delayTest];
});
}
结论
1.performSelector 如果不使用延时,程序会再子线程上直接调用该方法,方法会被调用
2.如果使用延时,在子线程中方法不会被调用,因为该方法等待定时器去调用,而该子线程中没有定时器,所以不会调用
3.解决2的方法就是使用dispatch_after里面会有一个定时器,来调用方法