NSProxy解决CADisplayLink ,NSTimer强引用target引起的无法释放问题
来源:互联网 发布:java 调用单例 编辑:程序博客网 时间:2024/04/25 12:16
最近开发中遇到个问题,在cell中开启了CADisplayLink并加入Runloop,在释放的时候,VC以及其他cell的dealloc都走了,只有开启定时器的cell不走dealloc方法。
查看发现NSTimer对target是强引用的导致了target泄漏,要解决这个问题必须打破循环引用,在NSTimer和target中间加多一层代理(Proxy),代理作为target被NSTimer强引用,同时弱引用真正的target,并对它转发消息。
对NSProxy是早有了解但是并没有真正的使用过,这次正好实践一下。
在使用NSProxy之前,简单复习一下Runtime的消息转发机制:
第一步,动态方法解析
+ (BOOL)resolveInstanceMethod:(SEL)sel;
+ (BOOL)resolveClassMethod:(SEL)sel;
第二步,备用接收者
- (id)forwardingTargetForSelector:(SEL)selector
如果一个对象实现了这个方法,并返回一个非nil的结果,则这个对象会作为消息的新接收者,且消息会被分发到这个对象。当然这个对象不能是self自身,否则就是出现无限循环。当然,如果我们没有指定相应的对象来处理aSelector,则应该调用父类的实现来返回结果。
第三步,完整消息转发
- (void)forwardInvocation:(NSInvocation *)invocation;
运行时系统会在这一步给消息接收者最后一次机会将消息转发给其它对象。对象会创建一个表示消息的NSInvocation对象,把与尚未处理的消息 有关的全部细节都封装在anInvocation中,包括selector,目标(target)和参数。我们可以在forwardInvocation 方法中选择将消息转发给其它对象。
- (nullable NSMethodSignature *)methodSignatureForSelector:(SEL)sel
消息转发机制使用从这个方法中获取的信息来创建NSInvocation对象。因此我们必须重写这个方法,为给定的selector提供一个合适的方法签名。我们的proxy 就是在第二步的时候,把target作为消息接收者响应方法。具体代码可以参考YY大神的YYWeakProxy
https://github.com/yehot/YYFPSLabel/blob/master/YYFPSLabel/YYFPSLabel/YYWeakProxy.m
- NSProxy解决CADisplayLink ,NSTimer强引用target引起的无法释放问题
- 利用NSProxy做NSTmer和CADisplayLink的target
- 利用NSProxy解决NSTimer内存泄漏问题
- 利用NSProxy解决NSTimer内存泄漏问题
- iOS 中的 NSTimer 强引用与释放
- 15.9 Swift解决闭包引起的循环强引用问题
- NSTimer循环引用不释放问题
- ARC之解决闭包引起的循环强引用
- ios NSTimer引起的循环引用,以及NSTimer的使用
- iOS中控制器的强引用释放问题
- NSTimer和CADisplayLink的用法
- NSTimer和CADisplayLink的用法
- CADisplayLink和NSTimer的区别
- CADisplayLink 和 NSTimer 的差异
- CADisplayLink和NSTimer的区别
- NSTimer循环引用的问题
- NSTimer的循环引用问题
- iOS NSTimer释放不掉的问题
- 排序——插入排序之直接插入排序
- 将setNativeProps传递给子组件
- Java JDBC
- Spring属性注入
- typedef 函数指针的用法
- NSProxy解决CADisplayLink ,NSTimer强引用target引起的无法释放问题
- 大数相乘
- HDU3466 Proud Merchants (01背包变形)
- 53. Maximum Subarray
- 美元跌破99!不仅特朗普效应失灵 这一大黑手也在偷袭
- HTTP协议原理
- Gym
- Java学习第二十一天之输入输出流
- nutz 无法注入HttpServletRequest对象