文档章节

Block的循环引用

余成海
 余成海
发布于 2016/08/30 12:12
字数 507
阅读 77
收藏 0

在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

© 著作权归作者所有

共有 人打赏支持
余成海
粉丝 61
博文 57
码字总数 29577
作品 0
杭州
iOS工程师
私信 提问
iOS中Block循环引用的问题

说到循环引用问题,想必大家都碰到过吧,比如在使用Block的时候,使用weakSelf来代替self解决等,但是对于这个,还是有不少可以探索的点,下面我就来说下,希望对大家有所帮助。 是否所有的B...

独处守心
09/29
0
0
如何优雅的处理循环引用(retain cycle)

什么是循环引用? 顾名思义, 就是几个对象某种方式互相引用, 形成了"环"。由于 Objective-C 内存管理使用引用计数的架构, 而并不是 GC(garbage collector), 而在 ARC(自动引用计数) 下所有 OC...

__block
06/13
0
0
ios block常见的错误(二)——循环引用

这篇博文继续block的常见错误——循环引用。 循环引用是很多初学者不能察觉的,其产生的原因,是block中的代码会对对象进行强引用。 读者请阅读示例代码1,并思考示例代码1所创建的对象能否被...

北方人在上海
2015/11/12
0
0
iOS 面试题~避免循环引用~解决方法

//联系人:石虎QQ:1224614774昵称:嗡嘛呢叭咪哄 一、概念: 循环引用:指的是多个对象相互引用时,使得引用形成一个环形,导致外部无法真正是否掉这块环形内存。其实有点类似死锁。 其实循环引用...

石虎132
2017/12/22
0
0
ios-常见的循环引用

介绍: 循环引用,指的是多个对象相互引用时,使得引用形成一个环形,导致外部无法真正是否掉这块环形内存。其实有点类似死锁。 举个例子:A->B->C->....->X->B ->表示强引用,这样的B的引用...

余成海
2016/04/12
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

[LintCode] Serialize and Deserialize Binary Tree(二叉树的序列化和反序列化)

描述 设计一个算法,并编写代码来序列化和反序列化二叉树。将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”。 如何反序列化或序列化二叉树是没有限制的,你...

honeymose
今天
5
0
java框架学习日志-7(静态代理和JDK代理)

静态代理 我们平时去餐厅吃饭,不是直接告诉厨师做什么菜的,而是先告诉服务员点什么菜,然后由服务员传到给厨师,相当于服务员是厨师的代理,我们通过代理让厨师炒菜,这就是代理模式。代理...

白话
今天
23
0
Flink Window

1.Flink窗口 Window Assigner分配器。 窗口可以是时间驱动的(Time Window,例如:每30秒钟),也可以是数据驱动的(Count Window,例如:每一百个元素)。 一种经典的窗口分类可以分成: 翻...

满小茂
今天
18
0
my.ini

1

architect刘源源
今天
16
0
docker dns

There is a opensource application that solves this issue, it's called DNS Proxy Server It's a DNS server that solves containers hostnames, if could not found a hostname that mat......

kut
今天
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部