「这是我参与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(@"测试");
}
复制代码