OC底层-Block本质(八、循环引用)

1,538 阅读2分钟

循环引用问题

循环引用是导致内存泄漏的主要问题。

我们来看一下代码

person没有被释放,产生了循环引用。

通过一张图看一下他们之间的内存结构:

上图中可以发现,Person对象和block对象相互之间产生了强引用,导致双方都不会被释放,进而造成内存泄漏。

解决循环引用问题 - ARC

首先为了能随时执行block,我们肯定希望person对block对强引用,而block内部对person的引用为弱引用最好。

使用__weak 和 __unsafe_unretained修饰符可以解决循环引用的问题

我们上面也提到过__weak会使block内部将指针变为弱指针。block对person对象为弱指针的话,也就不会出现相互引用而导致不会被释放了。

__weak 和 __unsafe_unretained的区别

__weak不会产生强引用,指向的对象销毁时,会自动将指针置为nil。因此一般通过__weak来解决问题。

__unsafe_unretained不会产生前引用,不安全,指向的对象销毁时,指针存储的地址值不变。

使用__block也可以解决循环引用的问题(三角恋...结果block劈了腿)

上述代码之间的相互引用可以使用下图表示:

在block内部使用变量使用的其实是__block修饰的变量生成的结构体__Block_byref_person_0内部的person对象,那么当person对象置为nil也就断开了结构体对person的强引用,那么三角恋爱的循环引用就自动断开。该释放的时候就会释放了。但是有弊端,必须执行block,并且在block内部将person对象置为nil。也就是说在block执行之前代码是因为循环引用导致内存泄漏的。