美文网首页
多线程下关于NSTimer不释放的问题

多线程下关于NSTimer不释放的问题

作者: Moclin | 来源:发表于2018-03-13 00:09 被阅读0次

    多线程下关于NSTimer不释放的问题

    前言

    前段时间由于项目需要,用到NSTimer,考虑到不占用主线程资源,故把timer放在子线程运行。前几天发现该controller pop之后并没有释放,问题定位到NSTimer这里。经过测试发现NSTimer在多线程下不释放的问题,但是找不到原因。由于工作关系,未能继续进行问题定位追踪,所以先记录下来。若有同行看到并且有答案,望赐教。

    正文

    使用子线程创建NSTimer

    代码:

    
    - (void)createThread {
    
        self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(createTimer) object:nil];
    
        [self.thread start];
    
    }
    
    
    
    - (void)createTimer
    
    {
    
        NSTimer *t = [NSTimer scheduledTimerWithTimeInterval:1.f target:self selector:@selector(repeat) userInfo:nil repeats:YES];
    
        self.timer = t;
    
        [[NSRunLoop currentRunLoop] run];
    
    }
    
    
    
    - (void)repeat
    
    {
    
        NSLog(@"repeat --- ");
    
    }
    
    
    
    - (void)stopTimer
    
    {
    
        [self.timer invalidate];
    
        self.timer = nil;
    
    }
    
    

    解开引用循环仍无法正常释放

    如上代码,这里会循环引用,

    self-->timer;

    timer-->self;

    self-->thread;

    thread(RunLoop)-->timer。

    理论上,在pop controller前调用- (void)stopTimer,self.timer会调用-(void)invalidate方法是的Timer对self的强引用解除,thread(RunLoop)对timer的强引用解除(详见invalidate的文档描述)。但是实际测试发现,调用- (void)stopTimer后虽然timer停止了,但是pop controller后,controller并没有释放。

    在同一子线程执行- (void)stopTimer

    查阅了一些资料,有这么一个说法:需在timer运行的线程下执行-(void)invalidate才有效果。抱着怀疑的态度(因为实际上,像上面的代码一样,在主线程调用,一样能使timer停止)在同一线程执行-(void)invalidate,如下代码:

    
    [self performSelector:@selector(stopTimer) onThread:self.thread withObject:nil waitUntilDone:YES];
    
    

    结果依旧是没有释放。

    在timer的repeat中执行- (void)stopTimer

    我也不知道为什么会做这样的尝试,或许是程序员的直觉吧。

    于是在repeat中添加如下代码:

    
    - (void)repeat
    
    {
    
        static int i = 0;
    
        NSLog(@"repeat --- ");
    
        i++;
    
        if (i >=2) {
    
            [self.timer invalidate];
    
        }
    
    }
    
    

    这一试,我更凌乱了,controller能够正常释放。因为和上面尝试是一样在同一线程执行-(void)invalidate的,但这样controller能够正常释放。反复思量,我找不出两者的区别在哪里,所以我很凌乱。

    结语

    我并没有解决这个问题,在这里只是提出了一个问题,并且做了一些思考和尝试,可能是自己知识还有所欠缺,之后会找时间再去研究一下这个问题。

    看到这里的你或许有答案,望赐教。

    相关文章

      网友评论

          本文标题:多线程下关于NSTimer不释放的问题

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