之前对iOS的性能优化,进行过实践经验的总结。但是当被问到如何显示当前页面的帧数时,还是木有回答出来,太尴尬?了。

面试官当场告诉我使用系统自带的CADisplayLink即可实现,回来之后马上从网上搜索资料。

从网上找到的显示当前页面帧数的demo,demo里使用YYFPSLabel来显示页面帧数的,YYFPSLabel是从YYKit框架抽取出来的。

附上显示帧数的代码如下:

- (void)testFPSLabel {

    _fpsLabel = [YYFPSLabel new];
    _fpsLabel.frame = CGRectMake(200, 200, 50, 30);
    [_fpsLabel sizeToFit];
    [self.view addSubview:_fpsLabel];
}

看了YYFPSLabel的实现代码,发现YYFPSLabel也是采用的CADisplayLink来实获取当前页面的帧数的。

计算当前页面帧数的核心代码如下:

    if (_lastTime == 0) {
        _lastTime = link.timestamp;
        return;
    }
    
    _count++;
    NSTimeInterval delta = link.timestamp - _lastTime;
    if (delta < 1) return;
    _lastTime = link.timestamp;
    float fps = _count / delta;
    _count = 0;

demo中还有另外的一个类YYWeakProxy,这个类的作用是为了解决循环引用问题。因为在使用CADisplayLink时,如果直接用 self 或者 weakSelf,都不能解决循环引用问题。

实现的原理: 使用 NSProxy 持有 NSTimer 的 target不再用 NSTimer 直接持有 self,就不会导致 timer 对 self 的循环强引用了

将 timer 的 target 从 self ,变成了中间人 NSProxy,timer 调用 target 的 selector 时,会被 NSProxy 内部转调用 self 的 selector。

中间人(NSProxy),这一精巧的设计,完美的解决了循环引用的问题。


蓝光95
210 声望16 粉丝

一名从业多年的软件开发者,做过5年的iOS开发,做过一年的react-native开发,有iOS性能优化经验,IM开发经验,会小程序的开发,现在在昆明从事移动前端开发的工作。