「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战」
关于 CADisplayLink
CADisplayLink 是用于同步屏幕刷新频率的计时器
-
CADisplayLink是一个和屏幕刷新率一致的定时器。CADisplayLink以特定模式注册到runloop后,每当屏幕显示内容刷新结束的时候,runloop就会向CADisplayLink指定的target发送一次指定的selector消息,CADisplayLink类对应的selector就会被调用一次。所以通常情况下,按照iOS设备屏幕的刷新率 60次/秒 -
iOS设备的屏幕刷新频率是固定的,
CADisplayLink在正常情况下会在每次刷新结束都被调用,精确度相当高。但如果调用的方法比较耗时,超过了屏幕刷新周期,就会导致跳过若干次回调调用机会 -
如果CPU过于繁忙,无法保证屏幕 60次/秒 的刷新率,就会导致跳过若干次调用回调方法的机会,跳过次数取决CPU的忙碌程度
CADisplayLink 常用方法及属性
-
创建方法
当把
CADisplayLink对象添加到runloop中后,并给它提供一个target和select在屏幕刷新的时候调用CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(run)]; [link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; -
停止方法
执行
invalidate操作时,CADisplayLink对象就会从runloop中移除,selector调用也随即停止,类似于NSTimer的invalidate方法[link invalidate]; link = nil; -
重要属性
-
timestamp只读属性,这个属性返回上一次屏幕刷新的时间戳。如果视频播放的应用,可以通过时间戳来获取上一帧的具体时间,来计算下一帧
-
duration只读属性,这个属性返回每帧之间的时间,也就是屏幕每次刷新之间的时间间隔。需要注意的是,该属性在
target的selector被首次调用以后才会被赋值。selector的调用间隔时间计算方式是:调用间隔时间 = duration × frameInterval -
frameInterval可读可写属性,
NSInteger类型的值,用来设置间隔多少帧调用一次selector方法,默认值是1,即每帧都调用一次。如果每帧都调用一次的话,对于iOS设备来说那刷新频率就是60HZ也就是每秒60次,如果将frameInterval设为2 那么就会两帧调用一次,也就是变成了每秒刷新30次 -
preferredFramesPerSecond可读可写属性,用来设置每秒刷新次数,默认值为屏幕最大帧率,目前是60。
实际的屏幕帧率会和
preferredFramesPerSecond有一定的出入,结果是由设置的值和屏幕最大帧率相互影响产生的。规则大概如下:如果屏幕最大帧率是60,实际帧率只能是15,20,30,60中的一种。如果设置大于60的值,屏幕实际帧率为60。如果设置的是26~35之间的值,实际帧率是30。如果设置为0,会使用最高帧率。
常用于如果在特定帧率内无法提供对象的操作,可以通过降低帧率解决
-
CADisplayLink 的使用
由于跟屏幕刷新同步,非常适合UI的重复绘制,如:下载进度条,自定义动画设计,视频播放渲染等
这里示例一个简单的例子
- (void)viewDidLoad {
[super viewDidLoad];
CADisplayLink *disLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(test)];
[disLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
//每秒钟调用多次 默认60.
disLink.preferredFramesPerSecond = 10;
}
- (void)test{
NSLog(@"测试");
}