「这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战」
关于GCD定时器
GCD定时器实际上是使用了 dispatch
源(dispatch source
),dispatch
源监听系统内核对象并处理。dispatch
类似生产者消费者模式,通过监听系统内核对象,在生产者生产数据后自动通知相应的 dispatch
队列执行,后者充当消费者。通过系统级调用,更加精准
GCD定时器常用方法
-
需要将dispatch_source_t timer设置为成员变量,不然会立即释放
@property (nonatomic, strong) dispatch_source_t timer;
-
创建定时器对象
//创建线程队列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //使用之前创建的队列来创建计时器 self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
参数1:
DISPATCH_SOURCE_TYPE_TIMER
为定时器类型
参数2、3:中间两个参数对定时器无用
参数4:在什么队列中使用 -
设置定时器
dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, 2.0 * NSEC_PER_SEC, 0.0 * NSEC_PER_SEC);
参数1:任务定时器
参数2:任务开始时间
参数3:任务间隔(单位均为纳秒)
参数4:可接受的误差时间,设置0即不允许出现误差 -
设置定时器任务
dispatch_source_set_event_handler(self.timer, ^{ });
-
启动定时器,GCD计时器创建后需要手动启动
dispatch_resume(self.timer);
-
暂停定时器,暂停的时候注意,多次暂停的操作会导致线程锁的现象,即多少次暂停,对应多少次的继续操作,即
dispatch_suspend
和dispatch_resume
是成对出现的,计时器才会继续工作dispatch_suspend(self.timer);
-
停止定时器
dispatch_source_cancel(self.timer);
优点:
- GCD定时器不依赖
runloop
,他是一个独立的体系 - 精度高,最小到1纳秒
- 没有
invalidate
方法 - 不需要手动管理内存(这里封装的target方式一定要注意循环引用)
GCD定时器的使用
示例:
@interface ViewController ()
@property (nonatomic, strong) dispatch_source_t timer;
@end
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_queue_t queue = dispatch_get_main_queue();
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, 2.0 * NSEC_PER_SEC, 0.0 * NSEC_PER_SEC);
dispatch_source_set_event_handler(self.timer, ^{
NSLog(@"定时任务");
});
dispatch_resume(self.timer);
}
log: