Block的循环引用
Block的循环引用
余成海 发表于2年前
Block的循环引用
  • 发表于 2年前
  • 阅读 67
  • 收藏 0
  • 点赞 0
  • 评论 0

【腾讯云】买域名送云解析+SSL证书+建站!>>>   

在ios常见的循环引用中曾经提到过block:

看看上面最基本的block循环应用,self包含block,block包含了self中的变量val,所以形成了循环应用,编译器给出了循环引用的警告,当然不是所有的block循环引用编译器都能给出警告,所以不要只依赖编译器的警告来判断循环引用,如:

解决的办法当然是使用__weak来修饰self

__weak typeof(self) weakSelf = self;
blkk =  ^{
    [weakSelf showLog];
};
blkk();

-------------------------------凌乱分割线-------------------------------

正常在栈上的block引用self是不会引起循环应用的,所以可以不使用weak来修饰self

void (^blkk)(void) =  ^{
    [self showLog];
};
blkk();

但是因为block的使用附有__strong的原因,虽然不会有循环引用,但是也会起到延长self对象的生命周期的效果,直到栈上的block释放了,才会释放self。

因此释放self可能会让程序出现问题,假如self监听了某些通知而修改公共资源什么的,所以这种情况下最好也使用weakself。

当然你也可能不希望self提前释放,因为你的block回调后需要进行完整操作,假如self释放了,你无法在block回调后来处理一些其他的事情,这时候你可以选择不使用weakself,也可以使用weakself+strongself。先看看weakself+strongself的写法:

__weak __typeof__(self) weakSelf = self;

createdTask = [self.sessionManager
              dataTaskWithRequest:request
              completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
              dispatch_async(self.responseQueue, ^{
                  __strong __typeof__(weakSelf) strongSelf = weakSelf;
.....

上面是AFNetworking的源码,在block前用了weakself,在block里用了strongself,这样做和直接不使用weakself有什么区别呢。

  block回调前结束self block回调后结束self
不使用weakself self 不释放 self不释放
weakself+strongself self已释放 self不释放
使用weakself self已释放 self已释放

所以根据情况的不同,大家可以选择使用哪种方式。当然最无脑的推荐还是使用weakself

标签: ios block weakself
  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 61
博文 56
码字总数 29577
×
余成海
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: