#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) CADisplayLink *displayLink;
@end
@implementation ViewController
{
dispatch_source_t _timer;
}
- (void)viewDidLoad {
[super viewDidLoad];
#if 0
// 第一种创建方式:
// [NSTimer scheduledTimerWithTimeInterval:<#(NSTimeInterval)#> target:<#(nonnull id)#> selector:<#(nonnull SEL)#> userInfo:<#(nullable id)#> repeats:<#(BOOL)#>];
#endif
#if 0
// 第二种创建方式:
// CADisplayLink 与屏幕的刷新率,一般屏幕的默认刷新次数为60/s
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)];
// 修改刷新频率,多少帧刷新一次
_displayLink.frameInterval = 60;
// 销毁
// [_displayLink invalidate];
// _displayLink = nil;
// 当添加到RunLoop中会立即执行
[_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
#endif
#if 1
__block int j = 0;
// 第三种创建方式:
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
// intervarlInSeconds 每个多久执行一次
// leewayInSeconds 允许出现多少误差,0为最精准
dispatch_source_set_timer(_timer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
// 执行的事件
dispatch_source_set_event_handler(_timer, ^{
NSLog(@"%d", j++);
});
// 执行
dispatch_resume(_timer);
// 停止
// dispatch_source_cancel(timer);
#endif
}
- (void)update
{
static int index = 0;
NSLog(@"%d", index++);
if (index == 5)
{
// 暂停
_displayLink.paused = YES;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 继续
_displayLink.paused = NO;
});
}
}
CADisplayLink是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器。
CADisplayLink 与 NSTimer 有什么不同?
iOS设备的屏幕刷新频率是固定的,CADisplayLink在正常情况下会在每次刷新结束都被调用,精确度相当高。NSTimer的精确度就显得低了点,比如NSTimer的触发时间到的时候,runloop如果在阻塞状态,触发时间就会推迟到下一个runloop周期。并且 NSTimer新增了tolerance属性,让用户可以设置可以容忍的触发的时间的延迟范围。CADisplayLink使用场合相对专一,适合做UI的不停重绘,比如自定义动画引擎或者视频播放的渲染。NSTimer的使用范围要广泛的多,各种需要单次或者循环定时处理的任务都可以使用。
在UI相关的动画或者显示内容使用 CADisplayLink比起用NSTimer的好处就是我们不需要在格外关心屏幕的刷新频率了,因为它本身就是跟屏幕刷新同步的。