iOS中为什么使用__weak和__strong可以解决block的循环引用?

在iOS中,循环引用是不可忽视的一个问题,因为循环引用极有可能会造成内存泄漏,是衡量一个app是否健康且高质量的标准之一。如何去解决循环引用呢,笔者在此提出三种解决方式:

1.使用__weak和__strong;

2.使用__block修饰变量,在block内部需要使用全部变量时暂用__block代替,在block外部再做有关全局变量的操作;

3.使用self作为block的参数,也可解决循环引用。

下面我们重点分析第一种情况,使用__weak和__strong解决循环引用:

在block内部如果需要使用实例方法或者实例变量,首先应定义: __weak typeof(self) weakSelf = self;

在block中可以再次定义strongSelf对weaSelf进行持有,如果可以确定block是同步执行的,那么可以不需要使用strong重新声明。接下来是我们的重点,为什么__weak可以解决循环引用:

1.__weak使用之后,会调用__objc_initWeak函数,storeWeak函数等,将要指向的对象地址(id  *location)以及指针(objc_object  *newObj)传入storeWeak函数,通过hash表映射,location作为key,newObj作为value,存储在weakTable中进行维护。weak指针指向对象,不会让对象的引用计数增加,所以block内部就不会持有self对象,破解循环引用;

2.为什么异步时需要使用strong再对对象重新声明?如果在异步执行的过程中,self被释放,会调用objc_clear_deallocating(id obj)方法,下一步调用clearDeallocating方法,紧接着调用

weak_clear_no_lock(weak_table_t  *weak_table, id referent)

函数,在hash表中根据key(对象地址)寻找weak指针的数组,遍历置空。所以为了避免self被释放掉导致后续流程无法走通,使用strong强引用弱指针,执行过程中weak指针就不会被释放,在执行完成之后再释放置空。

3.为什么strong不会造成循环引用呢?因为strong实在block内部创建的,属于局部变量,强引用的也是weak指针,在block执行完成后,strongSelf变量就会被释放,这个临时的“循环引用”就会被打破。

如有不正确之处,请各位读者评论指正,谢谢。(QQ:1309595446)

你可能感兴趣的:(iOS中为什么使用__weak和__strong可以解决block的循环引用?)