JPFPSStatus to CADisplayLink

今天看到了一个检测查看屏幕帧数的轮子——JPFPSStatus,就很好奇的去看了一下,发现不是很难,特此小记录下。

JPFPSStatus to CADisplayLink_第1张图片
JPFPSStatus效果图

发现其核心代码如下

displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkTick:)];
[displayLink setPaused:YES]; 
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

另外就是显示和移除啦

- (void)displayLinkTick:(CADisplayLink *)link {
    if (lastTime == 0) {
        lastTime = link.timestamp;
        return;
    }
    count++;
    NSTimeInterval interval = link.timestamp - lastTime;
    if (interval < 1) return;
    lastTime = link.timestamp;
    float fps = count / interval;
    count = 0;
    NSString *text = [NSString stringWithFormat:@"%d FPS",(int)round(fps)];
    [fpsLabel setText: text];
    
}
- (void)dealloc {
    [displayLink setPaused:YES];
    [displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}

说ji此处就是 CADisplayLink的运用,以及注意下将 runloop mode 改为NSRunLoopCommonModes就 OK 啦。

CADisplayLink

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

CADisplayLink 以特定的模式注册到runloop之后,每当屏幕需要刷新的时候,runloop就会调用CADisplayLink绑定的target上的selector,这时target可以读到 CADisplayLink 的每次调用的时间戳,用来准备下一帧显示需要的数据。

注意其这 duration、frameInterval 属性

@property(readonly, nonatomic) CFTimeInterval duration;
@property(nonatomic) NSInteger frameInterval;
  • duration: 提供了每帧之间的时间,也就是屏幕每次刷新之间的的时间。我们可以使用这个时间来计算出下一帧要显示的UI的数值。但是 duration 只是个大概的时间,如果CPU忙于其它计算,就没法保证以相同的频率执行屏幕的绘制操作,这样会跳过几次调用回调方法的机会。
  • frameInterval: 是可读可写的NSInteger型值,标识间隔多少帧调用一次selector方法,默认值是1,即每帧都调用一次。如果每帧都调用一次的话,对于iOS设备来说那刷新频率就是60HZ也就是每秒60次,如果将frameInterval 设为2 那么就会两帧调用一次,也就是变成了每秒刷新30次。

PS: iOS设备的屏幕刷新频率是固定的,CADisplayLink在正常情况下会在每次刷新结束都被调用,相对于 NSTimer 来说精确度相当高。特别是在UI相关的动画或者显示内容使用 CADisplayLink比起用NSTimer的好处就是我们不需要在格外关心屏幕的刷新频率了,因为它本身就是跟屏幕刷新同步的。

备注:

http://blog.csdn.net/wzzvictory/article/details/22417181
http://www.jianshu.com/p/c35a81c3b9eb
https://github.com/joggerplus/JPFPSStatus

你可能感兴趣的:(JPFPSStatus to CADisplayLink)