block 中强引用与弱引用
2016-07-07 本文已影响2581人
devZhang
在项目学习的时候,遇到 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】