阅读 215

Timer强引用问题与循环引用

Timer强引用

假设VC有一个timer正在执行,如果不调用[self.timer invalidate];,当我们pop回去的时候timer还会一直执行并且VC的dealloc不会调用,也就是VC一直没有析构

self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:weakSelf selector:@selector(fireHome) userInfo:nil repeats:YES];复制代码

为什么timer没有释放,来看下官方文档

//The object to which to send the message specified by aSelector when the timer fires. 
//The timer maintains a strong reference to this object until it (the timer) is invalidated.
//当timer fire的时候会对`target`进行强持有,直到调用 `invalidated`复制代码

这个时候就行程了一个强持有问题runloop -> timer -> self那是不是跟block一样weakself就可以解决呢,这个时候模型就变成了runloop -> timer -> weakSelf -> self经过测试还是不行的没有打破这层强持有关系.那为什么呢 weakself加入到了弱引用表中,但是weakself和self一样么,先验证下

2020-05-13 15:45:24.514059+0800 强引用[66904:226978] 9
(lldb) p &self
(TimerViewController **) $0 = 0x0000000116b33fc8
(lldb) p &weakSelf
(TimerViewController *const *) $1 = 0x00007ffee1ff2c08
(lldb) 
复制代码

发现他们是不相同的,只是指向了同一片地址.并且引用计数没有变化.并没有打破强持有关系,那么block为什么就可以,来我们看下block源码

void _Block_object_assign(void *destArg, const void *object, const int flags) {
    const void **dest = (const void **)destArg;
    switch (os_assumes(flags & BLOCK_ALL_COPY_DISPOSE_FLAGS)) {
      case BLOCK_FIELD_IS_OBJECT:
        /*******
        id object = ...;
        [^{ object; } copy];
        ********/

        _Block_retain_object(object);
      //objc 指针地址 weakself (self)
        *dest = object;
        break;
       default:
        break;
    }
}复制代码

const void **dest = (const void **)destArg;block操作的是指针地址,并没有直接持有self,只是持有了一个临时变量的指针地址self -> block  ->weakself (临时变量的指针地址) 所以打破了这层持有关系 而timer是直接操作的对象所以无法打破这层强引用关系


作者:JasonLee121
链接:https://juejin.cn/post/7047041467314864136

文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐