Block的循环引用

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

看看上面最基本的block循环应用,self包含block,block包含了self中的变量val,因此造成了循环应用,编译器给出了循环引用的警告,固然不是全部的block循环引用编译器都能给出警告,因此不要只依赖编译器的警告来判断循环引用,如:session

解决的办法固然是使用__weak来修饰selfasync

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

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

正常在栈上的block引用self是不会引发循环应用的,因此能够不使用weak来修饰selfcode

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

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

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

固然你也可能不但愿self提早释放,由于你的block回调后须要进行完整操做,假如self释放了,你没法在block回调后来处理一些其余的事情,这时候你能够选择不使用weakself,也可使用weakself+strongself。先看看weakself+strongself的写法:ci

__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编译器

相关文章
相关标签/搜索