Block的循环引用

在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回调前结束selfblock回调后结束self
不使用weakselfself 不释放self不释放
weakself+strongselfself已释放self不释放
使用weakselfself已释放self已释放

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

转载于:https://my.oschina.net/iq19900204/blog/739755

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值