block 中强引用与弱引用

作者: devZhang | 来源:发表于2016-07-07 13:21 被阅读2581次

    在项目学习的时候,遇到 block 内部使用强引用还是弱引用的一些内存问题,总结记录一下。

    创建一个测试 demo,包含一个普通的 person 类


    里面声明了一个字符串name 属性, 和一个 block 属性。
    另外,为了监测 person 对象是否被释放,在XFPerson.m 加上一段测试代码

    接着来到ViewController.m, 引入 person 类头文件,实例化一个 person 对象。
    我们来看以下这几种情况:

    block 内部没有使用外部变量

    给name 和 block 赋值



    可以看到代码执行完毕,block 内容被输出,person 对象被正常释放

    block 内部使用外部声明的强引用访问person 对象在 block 内部访问 person 的name 属性


    可以发现,代码执行完毕后,block 内容被输出,但并没有发现 person 对象被正常释放,此时会产生内存问题。

    block 内部使用外部声明的弱引用访问person 对象在 block 内部使用外部声明的弱引用访问person对象


    代码执行完毕后,可以看到 person 对象被正常释放。
    可能你会说,以后内部就使用外部声明的弱引用不就可以了,但是,你再看这种情况

    这时候你会发现,在打印 block 内容的之前,person 对象已经被释放了,自然,name 属性的值,也是空的了。

    block 内部有延迟操作的时候,使用外部声明的强引用

    这种情况是针对上面那个测试的,就是在延操作的时候,直接使用外部声明强引用



    这个时候,确实可以访问到 person 对象的name 属性值,但是,同样像最开始一样,block 会对 person 对象产生强引用,代码执行完毕后 person 对象没有被正常释放,导致内存问题。
    那么该怎么解决呢? 再看下面这种情况

    block 内部使用内部声明的强引用

    在 block 内部声明一个强引用指向外部声明的若引用,话可能有点绕,我们来看结果



    可以看到,person 的 name 属性值被打印出来,而且,person 对象也被正常释放。

    总结:
    如果【block内部】使用了【外部声明的强引用】访问【对象A】,那么【block内部】会自动产生于一个【强引用】指向【对象A】
    如果【block内部】使用了【外部声明的弱引用】访问【对象A】,那么【block内部】会自动产生于一个【弱引用】指向【对象A】

    相关文章

      网友评论

      • 布带:加上1.2.3.4.上下翻起来不容易弄混淆.
      • 香草的天空_821a:可以把dispatch操作放在外边吧,
        dispatch_async(dispatch_get_main_queue(), ^{
        person.block();
        });
      • 春泥Fu:学习了~ :grin:
      • liouly:block 内部有延迟操作的时候,对象会变成nil,po主知道这是什么原因么?
        devZhang:@liouly 我的理解是这样的----当调用 block 的时候,就要执行 block 里面的任务,而任务是延迟3秒才去执行,这个时候是系统内部有个强指针指向这个延迟操作, 同一时间,代码并不会停止,而会继续往下进行,因为block 内部是弱引用访问的对象,所以在代码执行到最后一行的时候,已经没有强指针指向对象了,对象就被释放了。 然后3秒时间到,执行延迟操作任务,发现这个时候要访问的对象已经被释放掉了,自然会为 nil。
        liouly:@张张张小烦 是啊,为什么延迟就会被提早释放,有没有什么见解?
        devZhang:@liouly 是不是我上面说的在 block 内部有延迟操作的时候使用了外部声明的弱引用那种情况? 如果是这样会导致延迟操作还没开始执行,对象已经被释放,就会变成 nil 。
      • 高浩浩浩浩浩浩:赞赞赞👍

      本文标题:block 中强引用与弱引用

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