如果在项目中有每隔一段时间定时执行某个函数的需求,那么大家首先想到的应该是NSTimer。其实CADisplayLink也能实现每隔一段时间定时执行函数。
官方API的定义是
A timer object that allows your application to synchronize its drawing to the refresh rate of the display.
CADisplayLink是一个定时器对象,它可以让你与屏幕刷新频率相同的速率来刷新你的视图
目前iOS中的屏幕刷新速率是60Hz。也就是每秒刷新60次。那么我们可以利用CADisplayLink对象使我们想要执行的代码块每秒执行60次。当然我们也可以设置CADisplayLink的属性preferredFramesPerSecond
来改变刷新次数为30次或15次。
CADisplayLink的使用
- 1.创建CADisplayLink对象。
+ (CADisplayLink *)displayLinkWithTarget:(id)target selector:(SEL)sel;
使用这个类方法来创建CADisplayLink对象,其中的参数sel就是要重复执行的函数。 - 2.把CADisplayLink对象加入runloop。
- (void)addToRunLoop:(NSRunLoop *)runloop forMode:(NSRunLoopMode)mode;
这个实例方法将CADisplayLink对象加入到指定mode的runloop中去。
实际使用:
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(refresh)];
[_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
CADisplayLink的方法和属性
- 1.
- (void)removeFromRunLoop:(NSRunLoop *)runloop forMode:(NSRunLoopMode)mode;
把指定mode的CADisplayLink对象从runloop中移除。这个实例对象适用于想要改变实例对象的mode,这时候就要先从当前mode中remove,然后再add。 - 2.
- (void)invalidate;
把CADisplayLink对象从所有runloop modes中移除。执行这个操作之后,CADisplayLink对象就没有加入任何的runloop,这样回调也不会在每次刷新屏幕的时候执行。 - 3.
@property(nonatomic) NSInteger preferredFramesPerSecond;
这个属性说明了间隔多少帧调用一次回调。默认是0,即每帧都调用回调,换句话说,就是一秒回调60次。如果这个属性值设为2,那么就是每两帧回调 一次,也就是每秒回调30次。 - 4.
@property(readonly, nonatomic) CFTimeInterval duration;
只读的CFTimeInterval值,表示两次屏幕刷新之间的时间间隔。需要注意的是,该属性在target的selector被首次调用以后才会被赋值。selector的调用间隔时间计算方式是:时间=duration×preferredFramesPerSecond。 - 5.
@property(readonly, nonatomic) CFTimeInterval timestamp;
只读的CFTimeInterval值,表示屏幕显示的上一帧的时间戳,这个属性通常被target用来计算下一帧中应该显示的内容。
打印timestamp值。
CADisplayLink和NSTimer的不同之处
- 1.原理不同
CADisplayLink是一个能让我们以和频率刷新率同步的频率将特定的内容画到屏幕上的定时器类。CADisplayLink以特定模式注册到runloop后,每当屏幕刷新结束的时候,runloop就会向CADisplayLink指定的target发送一次指定的selector消息, CADisplayLink类对应的selector就会被调用一次。
NSTimer以指定的模式注册到runloop后,每当设定的周期达到,runloop会向指定的target发送指定的selector。
由于CADisplayLink的屏幕刷新是硬件刷新,所以这个一般是没有延时的,所以用CADisplayLink作为定时器是非常精密的。但是我们知道NSTimer就不一样了,当runloop中有耗时的操作时,NSTimer的selector回调可能会延时执行或者干脆跳过。 - 2.周期设置方式不同
iOS设备的屏幕刷新频率是60Hz,也就是CADisplayLink的selector默认每秒执行60次,这个可以通过preferredFramesPerSecond这个属性来设置。例如我们设置preferredFramesPerSecond = 2,那么selector每秒被调用的次数就是60/2 = 30,因此CADisplayLink的周期设置方式就略显不变。
但是NSTimer的周期设置就很方便,想要设置每隔多少秒调用一次都可以。 - 3.使用场合不同
CADisplayLink的使用场合是比较单一的,多用于界面的不停重绘,比如视频播放的时候需要不同的获取下一帧的内容来渲染界面。
NSTimer的使用范围要广泛很多,各种单次执行或者定时执行的场合都可以应用。
参考:Core Animation系列之CADisplayLink
网友评论