博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf
阅读量:6698 次
发布时间:2019-06-25

本文共 1595 字,大约阅读时间需要 5 分钟。

转载,原文: http://blog.lessfun.com/blog/2014/11/22/when-should-use-weakself-and-strongself-in-objc-block/

当然有一个更详细的专题: http://tanqisen.github.io/blog/2013/04/19/gcd-block-cycle-retain/

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。

示例代码:

__weak __typeof__(self) weakSelf = self;    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{    [weakSelf doSomething];});
clang 的文档表示,在 doSomething 内,weakSelf 不会被释放。但,下面的情况除外:
__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];});
在 doSomething 中,weakSelf 不会变成 nil,不过在 doSomething 执行完成,调用第二个方法 doOtherThing 的时候,weakSelf 有可能被释放,于是,strongSelf 就派上用场了:
__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。

参考

原文作者: 

原文链接: 
版权声明:自由转载-非商用-非衍生-保持署名 | 

你可能感兴趣的文章
书摘---创业36条军规1:创业是怎么回事
查看>>
低学历者为何能骗取30万年薪职位
查看>>
Linux日志文件总管——logrotate
查看>>
一些不错的网站
查看>>
ffmpeg.exe 笔记
查看>>
PL/SQL复合变量
查看>>
MongoDB误删表恢复
查看>>
Tengine 安装配置全过程
查看>>
总链接
查看>>
HTTP必知必会
查看>>
DOS窗口的编码页从UTF-8调回GBK
查看>>
帮助孩子学会感恩_页数204_出版日期2015.03_完整版PDF电子书下载
查看>>
C语言编程规范
查看>>
android 标签对应的代码怎么写alignParentRight、marginRight
查看>>
在Linux系统安装Nginx及配置https加密访问
查看>>
jenkins 配置
查看>>
Linux学习134 Unit 8
查看>>
动手写了一个12306插件 chrome浏览器
查看>>
硬盘基本知识(一)
查看>>
初识Mysql(一)
查看>>