在做项目的时候大家应该都用到过 performSelector:withObject:afterDelay:
这个方法,不过这个方法也是有点小小的坑,最明显的一点就是:performSelector 方法如果调用了不存在的方法,编译器只会报警告不会报错,所以有可能造成运行崩溃,这个点大家应该都比较清楚。
另外一个坑点藏的有点深,平时我们一般都是在主线程去调用这个方法,当然是没有什么问题的。但是当我们在子线程去调用的时候,就会出现一些问题:方法并没有执行,为什么会出现这种状况呢?
这是因为子线程默认是没有开启 RunLoop 的,当 performSelector:withObject:afterDelay:
方法执行完毕后,线程可能已经死亡了,无法再去执行延时任务。
解决的方法其实也很简单,获取该子线程的 RunLoop,给他添加一个 port,防止 RunLoop 自动退出,然后调用 RunLoop 的 run 方法,当然可以使用 runUntilDate: 方法,让线程及时退出。
Example:
1 | // 在启动RunLoop之前,必须添加监听的输入源事件或者定时源事件,否则调用[runloop run]会直接返回,而不会进入循环让线程长驻。 |
最后一点,如果想要取消之前设定的延时任务,可以用 cancelPreviousPerformRequestsWithTarget:selector:object:
方法:
1 | [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(xxx) object:nil]; |