美文网首页
iOS 高级开发之内存管理之定时器

iOS 高级开发之内存管理之定时器

作者: iOS刘耀宗 | 来源:发表于2022-01-25 17:48 被阅读0次

    定时器内存管理 3 种方案 DEMO
    CADisplayLink、NSTimer使用注意
    CADisplayLink、NSTimer会对target产生强引用,target又对它们产生强引用,那么就会引发循环引用

    先看一段示例代码

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        self.view.backgroundColor = [UIColor whiteColor];
    //    self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(start)];
    //    [self.link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
        __weak typeof(self) weakSelf = self;
        self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:weakSelf selector:@selector(start) userInfo:nil repeats:YES];
        
    }
    
    //开始
    -(void)start {
        NSLog(@"%s",__func__);
    }
    
    -(void)dealloc {
        [self.timer invalidate];
    }
    

    timer 和 self 进行了相互引用.导致不能释放. 那么 传入一个 weak 修饰的 self 进去可以解决吗? 答案是不能的!

    猜测 timer 内部有一个strong 属性 对传进来的 target 进行强引用.所以导致不能释放

    解决方案: 之所以会导致内存不释放, 是因为循环引用导致的. 我们无法改变 NSTimer 里面的属性. 那么我们加入一个"第三者",来打破循环引用


    image.png

    主要代码:

    #import "TimerPersent.h"
    
    @implementation TimerPersent
    +(instancetype)initWithObject:(NSObject *)obj {
        TimerPersent *persent = [[TimerPersent alloc] init];
        persent.target = obj;
        return  persent;
    }
    //消息转发. 让传进来的 target去响应
    - (id)forwardingTargetForSelector:(SEL)aSelector {
        return  self.target;
    }
    @end
    

    NSTimer 的创建

      self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:[TimerPersent initWithObject:self] selector:@selector(start) userInfo:nil repeats:YES];
    

    完美解决.

    定时器采用使用 block,传入 weakSelf 可以解决循环引用

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        self.view.backgroundColor = [UIColor whiteColor];
    //    self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(start)];
    //    [self.link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
        __weak typeof(self) weakSelf = self;
    //    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:weakSelf selector:@selector(start) userInfo:nil repeats:YES];
        self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 repeats:true block:^(NSTimer * _Nonnull timer) {
            [weakSelf start];
        }];
        
    }
    
    //开始
    -(void)start {
        NSLog(@"%s",__func__);
    }
    
    -(void)dealloc {
        [self.timer invalidate];
        NSLog(@"销毁了");
    }
    

    相关文章

      网友评论

          本文标题:iOS 高级开发之内存管理之定时器

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