NSTimer实现定时器
- 调用下面的方法就会开启一个定时任务
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti
target:(id)aTarget
selector:(SEL)aSelector
userInfo:(id)userInfo
repeats:(BOOL)yesOrNo;
- 每隔ti秒,调用一次aTarget的aSelector方法,
- yesOrNo决定了
是否重复执行
这个任务 - 通过invalidate方法可以
停止
定时器的工作
- (void)invalidate;
- 一旦定时器被停止了,就不能再次执行任务
- 只能再次创建一个新的定时器才能执行新的任务
GCD定时器
-
创建GCD定时器
dispatch_source_t
,可以直接敲dispatch_source timer
就能看到一个创建GCD定时器的函数,会自动生成创建代码块// 创建定时器 // 第1个参数:资源的类型 // 第2个参数:函数句柄,一般不需要,直接传0 // 第3个参数:直接传0 // 第4个参数:任务的执行队列,如果是并发队列,这个方法内部会开新线程 dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatchQueue); // 设置定时器什么时候开始,每隔多久执行一次 // 第2个参数:什么时候开始,dispatch_time_t类型 // 第3个参数:每隔多久执行一次,单位是纳秒(1s = 10的9次方ns) // 第4个参数:leewayInSeconds字面意思是回旋的秒数,一般传0就可以了,单位是纳秒 // NSEC_PER_SEC表示1秒所含的纳秒数,在下面关键词解释有说明 dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, intervalInSeconds * NSEC_PER_SEC, leewayInSeconds * NSEC_PER_SEC); // 定时器要执行的任务 dispatch_source_set_event_handler(timer, ^{ // 代码逻辑 }); // 取消定时器时要执行的任务 dispatch_source_set_cancel_handler(timer, ^{ // 代码逻辑 }); // 启动定时器 dispatch_resume(timer);
-
一个完整的定时器的实现逻辑
@interface ViewController () /** 定时器(这里不用带*,因为dispatch_source_t就是个类,内部已经包含了*) */ @property (nonatomic, strong) dispatch_source_t timer; @end -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self gcdTimerTest]; } // 创建GCD定时器 -(void)gcdTimerTest { // 设定定时器延迟3秒开始执行 dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)); // 每隔2秒执行一次 uint64_t interval = (uint64_t)(2.0 * NSEC_PER_SEC); dispatch_source_set_timer(self.timer, start, interval, 0); // 要执行的任务 dispatch_source_set_event_handler(self.timer, ^{ NSLog(@"%s",__func__); }); // 启动定时器 dispatch_resume(self.timer); } - (dispatch_source_t)timer { if(_timer == nil) { // 创建队列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // dispatch_source_t,【本质还是个OC对象】 _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); } return _timer; }
-
取消定时器
// 停止定时器 dispatch_cancel(self.timer);
NSTimer和GCD器的定时区别
- NSTimer是在RunLoop中以特定Mode运行的,由于RunLoop中要处理各种事件,所以导致NSTimer并不是很精确
- GCD定时器不受RunLoop的Mode的影响,从时间精确到了
纳秒
看,这种定时器是非常精确的,深受开发者的喜爱
关键词解释
- SEC:秒(s)
- MSEC:毫秒(ms)
- USEC:微妙(μs)
- NSEC:纳秒(ns)
- PER:每
- 换算关系
- 1秒(s)=1000 毫秒(ms)
- 1毫秒(ms)=1000 微秒(μs)
- 1微秒(μs)=1000 纳秒(ns)
- 宏定义解释
// 1s = 1000000000ns
#define NSEC_PER_SEC 1000000000ull
// 1ms = 1000000ns
#define NSEC_PER_MSEC 1000000ull
// 1μs = 1000ns
#define NSEC_PER_USEC 1000ull
// 1s = 1000000μs
#define USEC_PER_SEC 1000000ull
- 延时1秒的写法,注意第二个参数的
单位是纳秒
// 推荐
dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC);
// 将微秒转换成纳秒(知道就行,一般开发不这么写)
dispatch_time(DISPATCH_TIME_NOW, 1000000 * NSEC_PER_USEC);