CGRunLoopTimerRef是基于时间的触发器,基本上说,就是NSTimer,他受到RunLoop的Mode影响,所以有点时候,我们说NSTimer可能会不准
但是CGD的定时器不受到RunLoop的影响
首先创建一个定时器
/** timer 本身就是一个对象,所以不要用*修饰,必须对他强引用,否则修释放*/
@property(strong,nonatomic) dispatch_source_t timer;
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//创建一个定时器
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
// dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC);
NSLog(@"main -%@",[NSThread currentThread]);
dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
dispatch_source_set_event_handler(self.timer, ^{
NSLog(@"%@",[NSThread currentThread]);
});
dispatch_resume(self.timer);
}
数据打印:每隔两秒打印一次,非常准时
2017-04-20 10:48:42.129 WXAllTest[1274:26444] main -<NSThread: 0x60800007c640>{number = 1, name = main}
2017-04-20 10:48:42.130 WXAllTest[1274:26492] <NSThread: 0x60000026f480>{number = 3, name = (null)}
2017-04-20 10:48:44.131 WXAllTest[1274:26492] <NSThread: 0x60000026f480>{number = 3, name = (null)}
2017-04-20 10:48:46.130 WXAllTest[1274:26492] <NSThread: 0x60000026f480>{number = 3, name = (null)}
2017-04-20 10:48:48.130 WXAllTest[1274:26492] <NSThread: 0x60000026f480>{number = 3, name = (null)}
2017-04-20 10:48:50.130 WXAllTest[1274:26492] <NSThread: 0x60000026f480>{number = 3, name = (null)}
2017-04-20 10:48:52.131 WXAllTest[1274:26492] <NSThread: 0x60000026f480>{number = 3, name = (null)}
2017-04-20 10:48:54.130 WXAllTest[1274:26492] <NSThread: 0x60000026f480>{number = 3, name = (null)}
2017-04-20 10:48:56.131 WXAllTest[1274:26492] <NSThread: 0x60000026f480>{number = 3, name = (null)}
2017-04-20 10:48:58.130 WXAllTest[1274:26492] <NSThread: 0x60000026f480>{number = 3, name = (null)}
2017-04-20 10:49:00.130 WXAllTest[1274:26492] <NSThread: 0x60000026f480>{number = 3, name = (null)}
如果想3秒钟之后再去启动定时器,每隔2s执行某件事怎么办?
dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
第一个参数表示timer,第二个是开始时间,默认是当前时间DISPATCH_TIME_NOW
,第三个参数是每隔几秒,单位是纳秒;
我们只要对第二个参数从新处理下就行,但是这个比较特殊,应该这样构建,否则无效
dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC);
停止一个定时器
//如何停止CGD定时器?
static int count = 0;
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//创建一个定时器
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
NSLog(@"main -%@",[NSThread currentThread]);
//设置一下timer的开始时间和间隔
dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
//timer每次执行的事情
dispatch_source_set_event_handler(self.timer, ^{
NSLog(@"%@",[NSThread currentThread]);
if (count == 4) {
dispatch_cancel(self.timer);
self.timer = nil;
}
count ++;
});
//启动timer,否则不能启动
dispatch_resume(self.timer);
}
2017-04-20 11:00:14.659 WXAllTest[1501:38869] main -<NSThread: 0x60800007d0c0>{number = 1, name = main}
2017-04-20 11:00:14.660 WXAllTest[1501:39450] <NSThread: 0x600000272540>{number = 3, name = (null)}
2017-04-20 11:00:16.660 WXAllTest[1501:39450] <NSThread: 0x600000272540>{number = 3, name = (null)}
2017-04-20 11:00:18.660 WXAllTest[1501:39450] <NSThread: 0x600000272540>{number = 3, name = (null)}
2017-04-20 11:00:20.661 WXAllTest[1501:39450] <NSThread: 0x600000272540>{number = 3, name = (null)}
2017-04-20 11:00:22.660 WXAllTest[1501:39450] <NSThread: 0x600000272540>{number = 3, name = (null)}
最后只打印了这些,说明关闭了