NSTimer循環引用

+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;

開發過程中肯定會用到計時器,一般都會選擇NSTimer,由於timer會在其內部對target強引用,而self.timer也會對timer強引用,這樣就會產生循環引用問題。


所以要解決循環引用就需要把這個循環斷開

方法一:
在NSTimer結束使用的時候,自動結束對NSTimer的引用,如在viewWillDisappear內停止timer並置空

   [_timer invalidate];
        _timer = nil;

方法二:
添加一箇中間變量變量target,打破self和timer的循環,讓target和timer相互引用,在self dealloc內切斷target和timer的循環引用

//添加中轉對象
self.target =  [NSObject new];
//動態添加方法
class_addMethod([_target class], @selector(fire),class_getMethodImplementation([self class], @selector(fire)),"v@:");
_timer = [NSTimer timerWithTimeInterval:1 target:_target selector:@selector(fire) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];

方法三:
添加代理進行消息轉發,打破self和timer的循環,讓target和timer相互引用,在self dealloc內切斷target和timer的循環引用

  _proxy = [JayProxy alloc];
    _proxy.target = self;
    _timer = [NSTimer timerWithTimeInterval:1 target:_proxy selector:@selector(fire) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];

demo已上傳git

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章