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】

相关文章

  • block 中强引用与弱引用

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

  • 浅谈OC中block

    Block的循环引用:block强引用self,self强引用block。解决方案:对self进行弱引用。 内部修...

  • iOS开发中常用的宏

    1,获取屏幕的大小,宽度和高度 用法: 2,弱引用/强引用 弱引用和强引用主要用在Block中,防止循环引用,导致...

  • iOS 中的内存管理优化

    闭包 外面将强引用对象转化为弱引用指针,防止循环引用 block内弱引用转换成strong强引用指针,防止多线程和...

  • Weak Reference Soft Reference Ph

    JAVA 中的引用 JAVA 中存在4种引用,由强到弱依次是强引用、软引用、弱引用、虚引用。 强引用(Strong...

  • Swift进阶 05:内存管理 & Runtime

    本文主要介绍Swift中的内存管理,涉及引用计数、弱引用、强引用、循环引用与Runtime等。 内存管理-强引用 ...

  • 工作笔记

    1、self在block里强引用怎么处理? 首先,在block外面声明一个弱引用对象__weak ViewCont...

  • iOS--强引用,弱引用 及strong, weak,retai

    强引用和弱引用:特点:在强引用中,有时会出现循环引用的情况,这时就需要弱引用来帮忙(__weak)。强引用持有对象...

  • 在block中对弱引用进行强引用

    打印结果: Optional()Opti...

  • block的使用

    一个对象中强引用了block,在block中又强引用了该对象,就会发生循环引用。1、变量在block中使用 2、对...

网友评论

  • 布带:加上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