performSelector afterDelay在子线程上调用不运行

平时我们想延迟一段代码的运行,最简单的方法就是使用 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里面会有一个定时器,来调用方法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 进程 什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内...
    45b645c5912e阅读 477评论 0 5
  • 在这篇文章中,我将为你整理一下 iOS 开发中几种多线程方案,以及其使用方法和注意事项。当然也会给出几种多线程的案...
    张战威ican阅读 614评论 0 0
  • 准备 Raspberry Pi 3B 开发板 微雪7'' HDMI树莓派专用电容触摸屏 Micro SD Card...
    qinwenbo阅读 1,446评论 1 1
  • 不怀念你了,你已经不是我认识的人了 就这样吧,那个QQ号我也不要了 嗯,后会无期。
    戏精w阅读 161评论 0 0