1 如果能找到合适的时机,无论timer是weak修饰还是strong修饰,主动调用 invalidate方法,那就调用invalidate,timer和控制器都能够释放
2 如果找不到合适时机,或者以防止漏写 invalidate方法,要注意:
一,要打破循环引用,添加__weak typeof(self) weakSelf = self;
二,要防止 timer直接引用self或者weakSelf
依照以上两点,iOS10之后用以下方法初始化,
__weak typeof(self) weakSelf = self;
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 repeats:YES block:^(NSTimer * _Nonnull timer) {
[weakSelf doSomeThing];
NSLog(@"----------------");
}];
iOS10之前,写个分类,参考文章 https://www.jianshu.com/p/2fe076e5e255,原理同系统方法相同
注意的是,在vc的dealloc方法中记得调用invalidate
- (void)dealloc {
[self.timer invalidate];
}
其实内部是 self(实例对象)--->timer——>self(类对象)——>block——>weakSelf——>self(实例对象)
当我们谈到循环引用时,其实是指实例对象间的引用关系。类对象在App杀死时才会释放,在实际开发中几乎不用关注类对象的内存管理
简化理解成 self-->timer——>block——>weakSelf——>self
这样打破 timer对self(或者weakSelf)的强引用,
既不是循环引用,又没有直接让timer引用self(weakSelf)所以退出控制器时 会调用 控制器的dealloc方法,不会造成内存泄漏