iOS里面使用的定时器类型通常有三种NSTimer、CADisplayLink、GCD。oop
一、最精准的定时器 - GCDatom
#import "ViewController.h" @interface ViewController () // 必需要有强引用,否则对象会被释放 @property (nonatomic , strong) dispatch_source_t timer ; @end @implementation ViewController -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ NSLog(@"__%s__",__func__); #warning 重复执行的GCD定时器 // 一、基于GCD的定时器,建立timer对象: // 参数一:source的类型DISPATCH_SOURCE_TYPE_TIMER 表示定时器类型 // 参数二:描述内容,好比线程ID // 参数三:详细描述内容 // 参数四:队列,决定GCD的队列在哪一个线程执行 dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0)); // 二、基于GCD的定时器,建立timer对象: // 参数一:定时器对象timer // 参数二:起始时间,DISPATCH_TIME_NOW表示从如今开始 // 参数三:多少时间内执行 // 参数四:精准度 绝对精准为0 dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 2.0 * NSEC_PER_SEC, 0 * NSEC_PER_SEC); // 三、执行内容 dispatch_source_set_event_handler(timer, ^{ NSLog(@"===%@===",[NSThread currentThread]); }); // 四、启动执行 dispatch_resume(timer); // 五、增长强引用 self.timer = timer; #warning 执行一次的GCD定时器 // 1. 延迟几秒后执行 double delayInSeconds = 2.0; // 2. 建立dispatch_time_t类对象 dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); // 3. 几秒后实际执行的事件 dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ //执行事件 }); } @end
二、最简单的定时器 - NSTimerspa
// 建立定时器 NSTimer *timer = [NSTimer timerWithTimeInterval:5 target:self selector:@selector(timerAction) userInfo:nil repeats:YES]; // 将定时器加入RUNLOOP的运行循环 [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
三、最适合作界面渲染的定时器 - CSDisplayLink 线程
// 1. 建立方法 self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)]; [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; // 2. 中止方法 [self.displayLink invalidate]; self.displayLink = nil; /**当把CADisplayLink对象add到runloop中后,selector就能被周期性调用,相似于重复的NSTimer被启动了;执行invalidate操做时,CADisplayLink对象就会从runloop中移除,selector调用也随即中止,相似于NSTimer的invalidate方法。**/ // 重要的属性: // frameInterval:NSInteger类型的值,用来设置间隔多少帧调用一次selector方法,默认值是1,即每帧都调用一次。 // duration:readOnly的CFTimeInterval值,表示两次屏幕刷新之间的时间间隔。须要注意的是,该属性在target的selector被首次调用之后才会被赋值。selector的调用间隔时间计算方式是:调用间隔时间 = duration × frameInterval。