- CADisplayLink
- NSProxy
- forwardingTargetForSelector:
一.CADisplayLink
(1) 为什么使用CADisplayLink而不是NSTimer?
CADisplayLink时,它的定时器方法就是屏幕每次刷新的时候就会调用
(2) 如何计算当前的FPS?
弄懂这个问题首先要知道什么是FPS,
百度知道 FPS
FPS"也可以理解为我们常说的“刷新率(单位为Hz)",例如我们常在CS游戏里说的“FPS值”。我们在装机选购显卡和显示器的时候,都会注意到“刷新率”。一般我们设置缺省刷新率都在75Hz(即75帧/秒)以上。例如:75Hz的刷新率刷也就是指屏幕一秒内只扫描75次,即75帧/秒。而当刷新率太低时我们肉眼都能感觉到屏幕的闪烁,不连贯,对图像显示效果和视觉感观产生不好的影响。
即:一秒刷新多少次
那么记录一下刷新次数,然后除以时间就可以了
这里主要是利用了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 了
项目 : YYText