循環(huán)引用原因:
初始化NSTimer
的時候,傳入的target
會被NSTimer
強引用绪杏,并且控制器強引用NSTimer
寄锐,所以產(chǎn)生循環(huán)引用。
self.timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
解決方案
1)合適的時機調(diào)用invalidate方法
- (void)viewDidDisappear {
[super viewDidDisappear];
[self.timer invalidate];
}
2)target使用中間類裁替,解決循環(huán)引用
我們可以添加一個中間類,將TimerProxy
的target
設(shè)為弱引用并指向當(dāng)前控制器就不會產(chǎn)生循環(huán)引用了
代碼:
- (void)viewDidLoad {
[super viewDidLoad];
self.timer = [NSTimer timerWithTimeInterval:1.0 target:[TimerProxy timerProxyWithTarget:self] selector:@selector(timerAction) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}
@interface TimerProxy : NSObject
@property (nonatomic, weak) id target;
+ (instancetype)timerProxyWithTarget:(id)target;
@end
@implementation TimerProxy
+ (instancetype)timerProxyWithTarget:(id)target
{
TimerProxy *instance = [TimerProxy new];
instance.target = target;
return instance;
}
- (id)forwardingTargetForSelector:(SEL)aSelector
{
return self.target;
}
@end
這里使用到了runtime
消息轉(zhuǎn)發(fā)機制貌笨,forwardingTargetForSelector
將消息轉(zhuǎn)發(fā)給當(dāng)前視圖控制器弱判,解決循環(huán)引用。