之前对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),这一精巧的设计,完美的解决了循环引用的问题。