Block(3)

讨论一个比较古老的问题。

__weak typeof(self) weakSelf = self;
self.block = ^{
    __strong typeof(weakSelf) strongSelf = weakSelf;
    NSLog(@"%@",strongSelf);
};

以上代码会不会循环引用,答案我们都知道–“不会”。
但是为什么不会,看了很多网上的资料,很多讲解的都不太准确/或者是漏掉了细节。

造成循环引用的原因,这里不多做解释。

首先看一下下面的代码为什么会造成强引用

self.block = ^{
    NSLog(@"%@",self);
};

在终端执行下面的命令查看clang rewrite 只有的代码。

xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-8.0.0 ViewController.m

可以看出ViewController变量是strong类型。
self是强引用block的,block再强引用self。这样就出现了循环引用的情况。

接下来看一下在文章开始提到的代码rewrite之后是什么样子。

由此可见即使block内部使用了strong指针重新指向,block捕获的self依然是weak类型的。
那么strong指针重新指向的作用是什么?那我们来看一下函数体。

为什么在这里使用strong不会造成循环引用? 因为strongSelf是局部变量,函数体结束后会对局部变量进行release。

总结:

block外部的__weak typeof(self) weakSelf = self;是解决self与block的循环引用,内部的__strong typeof(weakSelf) strongSelf = weakSelf; 是为了保证block执行过程中self是存在的。

You Might Also Like
发表评论