到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf
2016-07-06 11:25
274 查看
转自: http://blog.lessfun.com/blog/2014/11/22/when-should-use-weakself-and-strongself-in-objc-block/
Objective C 的
也会引起一些循环引用问题(
示例代码:
clang 的文档表示,在 doSomething 内,weakSelf 不会被释放。但,下面的情况除外:
在 doSomething 中,weakSelf 不会变成 nil,不过在 doSomething 执行完成,调用第二个方法 doOtherThing 的时候,weakSelf 有可能被释放,于是,strongSelf 就派上用场了:
Block 内,strongSelf 不会被释放。
如果在 Block 内需要多次 访问 self,则需要使用 strongSelf。
finally figured out weakSelf and strongSelf
Is
the weakSelf/strongSelf dance really necessary when referencing self inside a non-retained completion called from a UIViewController?
Objective C 的
Block是一个很实用的语法,特别是与GCD结合使用,可以很方便地实现并发、异步任务。但是,如果使用不当,Block
也会引起一些循环引用问题(
retain cycle)—— Block 会 retain ‘self’,而 ‘self‘ 又 retain 了 Block。因为在 ObjC 中,直接调用一个实例变量,会被编译器处理成 ‘self->theVar’,’self’ 是一个 strong 类型的变量,引用计数会加 1,于是,self retains queue, queue retains block,block retains self。
解决 retain circle
Apple 官方的建议是,传进 Block 之前,把 ‘self’ 转换成 weak automatic 的变量,这样在 Block 中就不会出现对 self 的强引用。如果在 Block 执行完成之前,self 被释放了,weakSelf 也会变为 nil。示例代码:
1 2 3 4 | __weak __typeof__(self) weakSelf = self; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [weakSelf doSomething]; }); |
1 2 3 45 | __weak __typeof__(self) weakSelf = self; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [weakSelf doSomething]; [weakSelf doOtherThing]; }); |
1 2 3 45 | __weak __typeof__(self) weakSelf = self; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ __strong __typeof(self) strongSelf = weakSelf; [strongSelf doSomething]; [strongSelf doOtherThing]; }); |
__strong确保在
Block 内,strongSelf 不会被释放。
总结
在 Block 内如果需要访问 self 的方法、变量,建议使用 weakSelf。如果在 Block 内需要多次 访问 self,则需要使用 strongSelf。
参考
Ifinally figured out weakSelf and strongSelf
Is
the weakSelf/strongSelf dance really necessary when referencing self inside a non-retained completion called from a UIViewController?
相关文章推荐
- JAVA获得图片的宽高
- C语言之实现控制台光标随意移动的实例代码
- 预处理指令
- SparkSQL 使用SQLContext读取csv文件 分析数据 (含部分数据)
- SPOJ LCA Lowest Common Ancestor
- 初级AD域渗透系列
- 问题--时景某些用户不能发表评论解决方案
- Ibatis 测试出SQL
- 获取URL中的某个参数/删除URL中的某个参数
- poj 2823 Sliding Window
- php 类中统一 调用方法处理
- js转义字符
- iOS 代理方法声明的两种形式:加号,减号,及使用场景说明
- object -c笔记之导入和继承
- hjr-通信原理(三):模拟信号数字载波编码
- hadoop wordcount 实例
- golang深度拷贝map
- 同步辅助类CountDownLatch用法
- 谷歌浏览器样式调试技巧点
- jqgrid固定表头