美文网首页
iOS NSTimer 对Target的释放和repeat的关系

iOS NSTimer 对Target的释放和repeat的关系

作者: 虫迹 | 来源:发表于2016-12-19 22:20 被阅读0次

    在一次实践中,创建了控制器,控制器中创建了timer和手势,控制器的view被addsubview到window上,手动或者3s后从window上移除。

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        
        self.view.backgroundColor=RGBA_COLOR(0, 0, 0, 0.4);
        _timer=[NSTimer timerWithTimeInterval:3.0
                                       target:self
                                     selector:@selector(action)
                                     userInfo:nil
                                      repeats:NO];
        UITapGestureRecognizer* tap= [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                            action:@selector(action)];
        [self.view addGestureRecognizer:tap];
    }
    

    并将timer加入到了当前的runloop中

    - (void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];
        [self startTimer];//开始计时
    }
    
    - (void)startTimer {
         [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
    }
    
    -(void)action
    {
        [_timer invalidate];
        _timer = nil;
        if (![self popNext]) {
            [self.view removeFromSuperview];
        }else {
            _timer=[NSTimer timerWithTimeInterval:3.0
                                           target:self
                                         selector:@selector(action)
                                         userInfo:nil
                                          repeats:NO];
            [self startTimer];
        }
        
    }
    

    运行在iOS9以下的系统手势触发会发上crash。

    屏幕快照 2016-12-19 22.03.48.png

    原因是该控制器创建后只有timer持有了该控制器。( timer对target对象强引用,当timer中repeat设置为NO时,timer到时间触发执行action后即对target不再引用;当timer中repeat设置为YES时,timer会持续持有target,直到手动invalidate timer后会释放。)当timer被invalidate后对象就释放了,再次访问timer就会报错。
    可是ios9及以上的系统就不会,由于ios9以上系统对内存回收机制做了修改,当对象函数运行中对对象本身进行释放时,会到函数运行结束完后才真正释放,ios9以前的系统会在函数运行中立即释放对象,不会等到函数运行结束,如果该函数之后对对象进行操作就会crash。

    相关文章

      网友评论

          本文标题:iOS NSTimer 对Target的释放和repeat的关系

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