JPFPSStatus源码学习

作者: 嗜糖63 | 来源:发表于2016-08-05 19:40 被阅读111次

    原文:Blog

    iOS 调试程序时 FPS 作为反应 ****UI**** 是否流畅的指标,一般的 ****60**** 的 FPS 值时, 程序界面就可以正常流畅地显示,而大型的运算处理等都会降低 FPS 值造成 ****UI**** 卡顿。如何优化程序逻辑以达到提升 FPS 值的目的不在本次的学习范围内,只是在开发过程中有用到 JPFPSStatus,代码量不多,学习下。

    首先介绍下主要使用类 CADisplayLink ****Xcode**** 给出的介绍如下:

    Class representing a timer bound to the display vsync.

    翻译应该是:

    类代表一个绑定到屏幕垂直同步显示的定时器。

    更加详细的说明见 官方文档

    需要注意的是

    CADisplayLink should not be subclassed.
    CADisplayLink 不可被继承。

    其创建实例的方法为
    Object-C:

    + (CADisplayLink *)displayLinkWithTarget:(id)target
                                    selector:(SEL)sel
    

    or Swift:

    init(target target: AnyObject, selector sel: Selector)
    

    参数解释:

    target: An object to be notified when the screen should be updated. // 当屏幕刷新是所通知的对象
    sel: The method to call on the target. // 所通知对象调用的方法

    实例应被加入 RunLoopmode 选择为: NSRunLoopCommonModes
    实例销毁时应从 RunLoop 中移除。
    实例创建后默认就开始向目标发送通知,可以设置 Bool 属性值 paused_暂停/开启_

    另一个关键的属性值 timestamp

    the time value associated with the last frame that was displayed. (read-only)
    与已显示的最后一帧相关联的时间值。 (只读)

    那么求 FPS -界面每秒显示帧数-的基本思路就可以得出, CADisplayLink 的实例被创建后,界面每次刷新 ****UI**** 都会调用所关联的 targetsel 方法,记录调用次数,在方法中我们拿到 CADisplayLink 实例,获取其属性值 timestamp 并记录,当 timestamp 相差 _1_ 时期间方法调用次数就是界面的 FPS。具体实现见源码:

    - (void)displayLinkTick:(CADisplayLink *)link {
        if (lastTime == 0) {
          // 初次调用直接记录时间
            lastTime = link.timestamp;
            return;
        }
    
        count++;
        NSTimeInterval interval = link.timestamp - lastTime;
        // 在时间差为1s后,count即为fps
        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];
        if (_fpsHandler) {
            _fpsHandler((int)round(fps));
        }
    
    }
    

    以上就是关于FPS计算的主要代码,源码中对系统是否进入活跃状态的通知进行接受,代码如下:

    [[NSNotificationCenter defaultCenter] addObserver: self
                                                     selector: @selector(applicationDidBecomeActiveNotification)
                                                         name: UIApplicationDidBecomeActiveNotification
                                                       object: nil];
    
            [[NSNotificationCenter defaultCenter] addObserver: self
                                                     selector: @selector(applicationWillResignActiveNotification)
                                                         name: UIApplicationWillResignActiveNotification
                                                       object: nil];
    

    接受通知的方法第一次遇到,记录学习。

    • 整体实现过程并不复杂,源码使用的是 Object-C 之后可以用 Swift 实现一遍(已实现: Demo )。

    • 不理解的是,源码将 fps 显示的 UILabel 加载到系统的 rootViewController 上,也就是说在其他界面是无法显示的,可以加到 Window 上以达到在所有页面显示的目的。

    相关文章

      网友评论

        本文标题:JPFPSStatus源码学习

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