在上一篇关于RunLoop的文章中,定时器是需要在开启runloop的线程中才能工作。但是,runloop是一直在循环运行,监听所有的source,timer和selector的。所以,在运行定时器的时候,runloop可能还需要处理其他事件,因此会造成定时器的一些误差,如果我们想让定时器脱离runloop,那么,这里有一种GCD的定时器可以使用,话不多少,直接上代码,已经写好详细注释:
@interface ViewController ()
//定时器这里不用带*,dispatch_source_t自带*
@property (nonatomic, strong) dispatch_source_t timer;
@end
@implementation ViewController
int count = 0;
- (void)viewDidLoad {
[super viewDidLoad];
//获得一个全局队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//创建一个定时器
/**
*dispatch_source_type_t type:需要创建的类型
*uintptr_t handle:0
*unsigned long mask:0
*dispatch_queue_t queue:队列
*本质还是OC对象
*/
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
NSLog(@"%@", self.timer);
//设置定时器的各种属性(几时开始任务,每隔多久执行一次)
/**
*dispatch_time_t when:开始事件
*int64_t delta:事件增量
*/
dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, 3.0 * NSEC_PER_SEC);
/**
GCD的事件参数一般是纳秒
*dispatch_time_t start:开始任务的时间
*uint64_t interval:纳秒 1秒 = 10的9次方纳秒
*/
dispatch_source_set_timer(self.timer, start, 2 * NSEC_PER_SEC, 0);
//设置回调
dispatch_source_set_event_handler(self.timer, ^{
NSLog(@"%@------", [NSThread currentThread]);
count++;
if (count == 4) {
//取消定时器
dispatch_cancel(self.timer);
self.timer = nil;
}
});
//启动定时器
dispatch_resume(self.timer);
}