- CADisplayLink
- NSProxy
- forwardingTargetForSelector:
一.CADisplayLink
(1) 为什么使用CADisplayLink而不是NSTimer?
CADisplayLink时,它的定时器方法就是屏幕每次刷新的时候就会调用
(2) 如何计算当前的FPS?
弄懂这个问题首先要知道什么是FPS,
即:一秒刷新多少次
那么记录一下刷新次数,然后除以时间就可以了
这里主要是利用了CADisplayLink
的时间戳属性timestamp
在CADisplayLink调用的方法里有以下代码:
_count++; // 记录刷新次数
NSTimeInterval delta = link.timestamp - _lastTime;
if (delta < 1) return;
_lastTime = link.timestamp;
float fps = _count / delta;
_count = 0;
这样就得到FPS了
(3) 如何解决循环引用问题?
CADisplayLink
对象 _line
被控制器持有,_line
又持有控制器作为Target
,这样如果在控制器的dealloc
里[_link invalidate];
是没用的,因为根本不会去到dealloc
里;
有个比较不好的解决方式是,在viewWillDisappear
里[_link invalidate];
,但是这并不是一个好的解决办法,因为如果push到其他页面,是不需要停止定时器的;
这就引出了NSProxy
,这是我接触的第一个非NSObject的子类;
遵守<NSObject>
协议
@interface NSProxy <NSObject> {
Class isa;
}
可以用NSProxy
作为中间人,弱引用控制器,
那target
如何调用控制器实现的方法呢?
消息转发!
在NSProxy
的声明文件里
被注释了,但是重写该方法,还是能够起作用,(或者是其他我不知道的原因)
以上,就可以在退出当前控制器正确释放 timer 了
被释放.jpeg