美文网首页
防止NSTimer内存循环应用的解决办法之二

防止NSTimer内存循环应用的解决办法之二

作者: 王正魁 | 来源:发表于2022-09-05 13:49 被阅读0次
直接官方介绍看图
image

target强引用,引用计数+1,因此避免循环饮用的理论:

@property (weak ,nonatomic) NSTimer *timer;这样写不通的。因为target引用计数已经+1,target如果是ViewController,页面栈,pop出时,引用计数不会变成0,因此不会调用deallocViewController依然在。

调用NSTimer方法中的invalidate,可以将target引用计数-1,由此可以解决内存泄漏问题。

NSTime中Block官方介绍:
image

官方介绍:Block的方式可以避免循环引用

Block的方式,NSTimer不会将target引用计数+1,因此,只关注Block循环引用问题即可。target会调用dealloc
需要在dealloc中调用NSTimerinvalidate方法,

如果不调用NSTimerinvalidate方法,NSTimer会一直执行,而targetnil。具体原因和Runloop有关系,后续我们单独再讲RunloopNSTimer的关系

调试代码如下

@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");
}

相关文章
防止NSTimer内存循环应用的解决办法之一

相关文章

网友评论

      本文标题:防止NSTimer内存循环应用的解决办法之二

      本文链接:https://www.haomeiwen.com/subject/tsivnrtx.html