如何解决NSTimer的循环引用

本文详细解析了NSTimer不当使用导致循环引用的原因,并提供了解决方案,包括在适当时机释放timer及利用NSProxy来避免这一问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Demo地址

我们都知道,NSTimer使用不当会造成循环引用。为什么会造成循环引用呢,关键的点还是在于:

[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(printNum:) userInfo:nil repeats:YES];
复制代码

方法的repeates,经过我的测试,当将repeats参数设置为YES的时候,NSTimer内部应该就会强引用target,而Runloop又强引用了target, target又引用了NSTimer,之所以这里用引用是,不管你的timer是weak or strong,都还是会造成循环引用。

target -> timer
timer -> target
runloop -> timer
复制代码

->符号表示强引用

如何破解这个循环引用呢

其实方法很简单,那就是在合适的时候,将timer给释放掉:

合适的时机有:
在viewWillDisappear的时候
在用户触发比如某个方法的时候,叫做stopTimer,里面就可以写释放timer的操作
复制代码

但是很多时候,我们都会忘记做这些释放的操作,因此,弱target了解一下。

使用NSProxy解决

关于什么是NSProxy呢,我的理解就是,是一个实现了NSObject协议,然后根级跟NSObject相同的一个抽象类,为啥说是抽象类呢,因为NSProxy里面压根就没有实例化的方法,应该也是为了防止人为的滥用吧。

两个必须实现的方法:

- (void)forwardInvocation:(NSInvocation *)invocation
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
复制代码

相信了解OC消息转发的朋友一定对这两个方法不陌生吧,这两个方法都是配套出现的,即methodSignatureForSelector方法构造一个invocation,然后forwardInvocation方法执行。这一步也是防止因为找不到方法而奔溃的最后一步。

PS:消息转发的机制,即NSObject类接受到消息的时候,会先从当前类中找是否存在这个方法,找不到则继续沿着父类往上找,如果都找不到的话,那么不要急,还有三个步骤做保证,即先会在resolveInstanceMethod和-forwardingTargetForSelector:做处理,如果也没有的话,那么就会用到上面的两个:forwardInvocation和methodSignatureForSelector方法了,如果都找不到的话,那么才会奔溃。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值