直接官方介紹看圖
將target
強引用非春,引用計數(shù)+1,因此避免循環(huán)飲用的理論:
@property (weak ,nonatomic) NSTimer *timer;
這樣寫不通的席怪。因為target
引用計數(shù)已經(jīng)+1,target
如果是ViewController
纤控,頁面棧挂捻,pop
出時,引用計數(shù)不會變成0船万,因此不會調(diào)用dealloc
刻撒,ViewController
依然在。
調(diào)用NSTimer
方法中的invalidate
耿导,可以將target
引用計數(shù)-1声怔,由此可以解決內(nèi)存泄漏問題。
NSTime中Block官方介紹:
官方介紹:Block的方式可以避免循環(huán)引用
Block的方式舱呻,NSTimer
不會將target
引用計數(shù)+1醋火,因此,只關(guān)注Block循環(huán)引用問題即可。target
會調(diào)用dealloc
芥驳。
需要在dealloc
中調(diào)用NSTimer
的invalidate
方法介粘,
如果不調(diào)用NSTimer
的invalidate
方法,NSTimer
會一直執(zhí)行晚树,而target
是nil
姻采。具體原因和Runloop
有關(guān)系,后續(xù)我們單獨再講Runloop
和NSTimer的關(guān)系
調(diào)試代碼如下
@property (strong ,nonatomic) NSTimer *timer;
- (void)dealloc {
NSLog(@"Timer invalidate 前 = %ld",CFGetRetainCount((__bridge CFTypeRef)(self.timer)));
[self.timer invalidate];
NSLog(@"Timer invalidate 后 = %ld",CFGetRetainCount((__bridge CFTypeRef)(self.timer)));
NSLog(@"TestVC釋放了%@",self);
}
- (void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
// [self.timer invalidate];
// NSLog(@"retainCount3 = %ld",CFGetRetainCount((__bridge CFTypeRef)(self)));
// self.timer = nil;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
// NSLog(@"retainCount0 = %ld",CFGetRetainCount((__bridge CFTypeRef)(self)));
[self creatTimer];
}
- (void)creatTimer {
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
// [self.timer fire];
}
- (NSTimer*)timer{
if(_timer==nil) {
__weak typeof(self) weakSelf = self;
// NSLog(@"retainCount1 = %ld",CFGetRetainCount((__bridge CFTypeRef)(self)));
// _timer = [NSTimer timerWithTimeInterval:1 target:weakSelf selector:@selector(timerForOverTimeOrder:) userInfo:weakSelf repeats:YES];
// NSLog(@"定時器前%@",weakSelf);
_timer = [NSTimer timerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
// NSLog(@"fafafdfadfadxf%@",weakSelf);
NSLog(@"retainCount4 = %ld",CFGetRetainCount((__bridge CFTypeRef)(timer)));
// NSLog(@"fafafdfadfadxf%@",timer.userInfo);
// NSLog(@"dfafdada%@",self);
}];
NSLog(@"retainCount2 = %ld",CFGetRetainCount((__bridge CFTypeRef)(self.timer)));
}
return _timer;
}
- (void)timerForOverTimeOrder:(id)info {
NSLog(@"%@",info);
// NSLog(@"1111");
}
相關(guān)文章
防止NSTimer內(nèi)存循環(huán)應用的解決辦法之一