iOS中延时方案主要有以下三种:
*NSObject的方案
*NSTimer的方案
*GCD方案
用法介绍
NSObject延时实现
关键的几点:
*该延时任务是执行在当前线程的当前的runloop中
*默认的延时任务执行模式是NSDefaultRunLoopMode
*延时任务的执行得确保当前线程的runloop是启动的。
默认添加到当前线程的runloop中去
使用NSTimer时,需要注意的时,target对象会持有timer这个实例,所以需要避免与target导致的相互持有,谁都销毁不掉的问题
GCD方案
使用这种方案,我们比较常见的就是
1
2
3
4
5
6
7
8
|
//when:通过dispatch_time()或dispatch_walltime()返回时间。
//queue: 执行操作的队列
//block: 需要执行的操作
void
dispatch_after(dispatch_time_t when,dispatch_queue_t queue,dispatch_block_t block);
//该方法是异步添加执行操作的。
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(
0.25
* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self delaySome];
});
|
很显然dispatch_after实现延时任务很有优势,不用处理线程中runloop的问题,调用的对象不会被强引用。
虽然通过这种方式的有事很明显,但是他还是有一个缺点的,就是我们不能够手动把这个任务取消掉。
其实不用这种方式,我们也能够自己使用GCD实现可以取消的定时操作。
1
2
3
4
5
6
7
8
9
10
|
dispatch_queue_t queue = dispatch_get_global_queue(
0
,
0
);
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
0
,
0
, queue);
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW,
2.0
* NSEC_PER_SEC,
1.0
* NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{
[self delaySome];
});
dispatch_resume(timer);
//可以通过这个当时取消定时器任务
dispatch_cancel(timer);
//如果这个过程中传递的参数中有self持有的对象,[self delaySome]中的self得改成weakSlef;比如为了方便取消任务,self持有了timer;
|
注意:timer没有被销毁或是取消时,会一直调用延时任务,也就是repeats为yes。
其实我们可以简单的把这个gcd的过程封装成NSTimer的一样的使用效果。