美文网首页
[iOS] CADisplayLink

[iOS] CADisplayLink

作者: 沉江小鱼 | 来源:发表于2021-02-05 14:00 被阅读0次

1. 简介

CADisplayLink 是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器。

我们在应用中创建一个CADisplayLink对象,把它添加到一个runloop中,并给它提供一个targetselector在屏幕刷新的时候调用。一但CADisplayLink以特定的模式注册到runloop之后,每当屏幕需要刷新的时候,runloop就会调用CADisplayLink绑定的target上的selector,这时target可以读到CADisplayLink的每次调用的时间戳,用来准备下一帧显示需要的数据。

在添加进runloop的时候我们应该选用高一些的优先级,来保证动画的平滑。可以设想一下,我们在动画的过程中,runloop被添加进来了一个高优先级的任务,那么,下一次的调用就会被暂停转而先去执行高优先级的任务,然后在接着执行CADisplayLink的调用,从而造成动画过程的卡顿,使动画不流畅。

2. API


/*
需要注意 定时器对象创建后 并不会马上执行 需要添加到runloop中
*/
+ (CADisplayLink *)displayLinkWithTarget:(id)target selector:(SEL)sel;
//将当前定时器对象加入一个RunLoop中
- (void)addToRunLoop:(NSRunLoop *)runloop forMode:(NSRunLoopMode)mode;
//将当前定时器对象从一个RunLoop中移除 如果这个Runloop是定时器所注册的最后一个  移除后定时器将被释放
- (void)removeFromRunLoop:(NSRunLoop *)runloop forMode:(NSRunLoopMode)mode;
//将定时器失效掉 调用这个函数后 会将定时器从所有注册的Runloop中移除
- (void)invalidate;
//当前时间戳
@property(readonly, nonatomic) CFTimeInterval timestamp;
//距离上次执行所间隔的时间
@property(readonly, nonatomic) CFTimeInterval duration;
//预计下次执行的时间戳
@property(readonly, nonatomic) CFTimeInterval targetTimestamp;
//设置是否暂停
@property(getter=isPaused, nonatomic) BOOL paused;
//设置预期的每秒执行帧数 例如设置为1 则以每秒一次的速率执行
@property(nonatomic) NSInteger preferredFramesPerSecond CA_AVAILABLE_IOS_STARTING(10.0, 10.0, 3.0);
//同上 
@property(nonatomic) NSInteger frameInterval
  CA_AVAILABLE_BUT_DEPRECATED_IOS (3.1, 10.0, 9.0, 10.0, 2.0, 3.0, "use preferredFramesPerSecond");
  

3. 具体使用

可以用来监测FPS(FPS = Frames Per Second 每秒渲染多少帧)的值,通常情况下,屏幕会保持60hz/s的刷新速度,每次刷新时会发出一个屏幕刷新信号,我们可以使用CADisplayLink通过屏幕刷新机制来展示fps值:

@interface ViewController ()

@property (nonatomic, assign) NSInteger count;
@property (nonatomic, assign) NSTimeInterval lastTime;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkMethod:)];
    [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}

- (void)displayLinkMethod:(CADisplayLink *)displayLink{
    if(_lastTime == 0){
        _lastTime = displayLink.timestamp;
        return;;
    }
    _count++;
    NSTimeInterval delta = displayLink.timestamp - _lastTime;
    if(delta < 1) return;
    _lastTime = displayLink.timestamp;
    CGFloat fps = _count / delta;
    _count = 0;
    
    NSInteger intFps = (NSInteger)(fps + 0.5);
    NSLog(@"%d",intFps);
}

相关文章

网友评论

      本文标题:[iOS] CADisplayLink

      本文链接:https://www.haomeiwen.com/subject/utnwtltx.html