之前对iOS的性能优化,进行过实践经验的总结。但是当被问到如何显示当前页面的帧数时,还是木有回答出来,太尴尬?了。
面试官当场告诉我使用系统自带的CADisplayLink
即可实现,回来之后马上从网上搜索资料。
从网上找到的显示当前页面帧数的,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),这一精巧的设计,完美的解决了循环引用的问题。