前言:打印retainCount
eg:在block内部使用self不提示循环引用⚠️(self !->testBlock->self)(这种情况block外部和内部self的引用计数相同)
1、在block内部使用self提示循环引用⚠️(self->testBlock->self)
2、使用(__weak typeof(self) weakSelf = self;)解除⚠️(这时block内部weakSelf比和self的引用计数+1,但是内部不强引用self,不构成循环引用)(问题:如果self在block内部使用之前销毁(不被持有),weakSelf的生命周期和self是一样的,导致weakSelf也销毁)(将强引用的对象转为弱引用指针,防止了 Block 和对象之间的循环引用)
3、使用(__strongtypeof(weakSelf) strongSelf = weakSelf;)(这时block内部在这行代码前weakSelf比和self的引用计数+1,之后weakSelf比和self的引用计数+2,strongSelf和self引用计数一样)(将weakSelf 的弱引用转换成 strongSelf 这样的强引用指针,防止了多线程和 ARC 环境下弱引用随时被释放的问题)
注意⚠️:
一、weakSelf 位于 Block 的外面,strongSelf 位于 Block 的里面。从内存管理的角度来看,weakSelf 是要比 strongSelf 的声明周期要长的。这样就形成了从弱引用到强引用,再从强引用到弱引用的一种变化,也称作 weak-strong dance。
二、之所以在Block的代码执行之前加上这样一个非nil判断,是为了防止在把 weakSelf 转换成 strongSelf 之前 weakSelf 就已经为 nil 了,这样才能确保万无一失。