美文网首页
iOS NSTimer导致内存泄露问题

iOS NSTimer导致内存泄露问题

作者: HCL黄 | 来源:发表于2020-03-17 14:32 被阅读0次

    通常情况下

    • 初始化NSTimer
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
        [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
    }
    
    
    • 执行timer方法
    - (void)timerAction {
        NSLog(@"timerAction");
        TimerInteger += 1;
        self.label.text = @(TimerInteger).stringValue;
    }
    
    • 最后销毁控制器的时候停止定时器并置空
    - (void)dealloc {
        NSLog(@"dealloc");
        [self.timer invalidate];
        self.timer = nil;
    }
    

    然而当我们退出控制器的时候,并不会调用dealloc,导致定时器一直存在,这样就有可能导致内存得不到释放,从而导致内存泄露

    通过中间变量来解决这一问题

    • 新建一个LATimerTarget对象
    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface LATimerTarget : NSObject
    
    @property (nonatomic, copy) void(^targetBlock)(void);
    
    - (void)timerTargetAction;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    #import "LATimerTarget.h"
    
    @implementation LATimerTarget
    
    - (void)timerTargetAction {
        NSLog(@"timerTargetAction");
        if (self.targetBlock) {
            self.targetBlock();
        }
    }
    @end
    
    • NSTimertarget设置为LATimerTarget对象,selector选择器调用LATimerTarget的方法- (void)timerTargetAction;,控制器需要处理的逻辑在LATimerTargettargetBlock进行处理
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor whiteColor];
        
        self.label = [[UILabel alloc] init];
        self.label.backgroundColor = [UIColor greenColor];
        self.label.font = [UIFont systemFontOfSize:20];
        self.label.frame = CGRectMake(0, 100, 200, 100);
        [self.view addSubview:self.label];
        
        /**
         当target为self的时候,退出该控制器时,dealloc是不会调用的,这会导致内存泄露
         */
    //    self.timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
    //    [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
        
        /**
         target设置为LATimerTarget对象,并且在LATimerTarget新增timerTargetAction方法
         通过targetBlock回调,进行UI逻辑处理
         这个时候我们退出该控制器时,dealloc调用,移除定时器
         */
        LATimerTarget *target = [[LATimerTarget alloc] init];
        __weak __typeof(&*self)weakSelf = self;
        target.targetBlock = ^{
            TimerInteger += 1;
            weakSelf.label.text = @(TimerInteger).stringValue;
        };
        self.timer = [NSTimer timerWithTimeInterval:1 target:target selector:@selector(timerTargetAction) userInfo:nil repeats:YES];
        [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
    }
    

    代码在此

    相关文章

      网友评论

          本文标题:iOS NSTimer导致内存泄露问题

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