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];
});

clang 的文档表示,在 doSomething 内,weakSelf 不会被释放。但,下面的情况除外:

1
2
3
4
5
__weak __typeof__(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[weakSelf doSomething];
[weakSelf doOtherThing];
});

在 doSomething 中,weakSelf 不会变成 nil,不过在 doSomething 执行完成,调用第二个方法 doOtherThing 的时候,weakSelf 有可能被释放,于是,strongSelf 就派上用场了:

1
2
3
4
5
6
__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。

参考

原文作者: lslin
原文链接: http://blog.lessfun.com/blog/2014/11/22/when-should-use-weakself-and-strongself-in-objc-block/
版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0

最新文章

  1. ASP.NET 开发必备知识点(2):那些年追过的ASP.NET权限管理
  2. 经典案例:那些让人赞不绝口的创新 HTML5 网站
  3. Python关键字yield的解释(stackoverflow)
  4. js jquery版本的 金额千分位转换函数(非正则,效率极高)
  5. js_day8
  6. Servlet3.1规范和JSP2.3规范
  7. c# for 和 foreach 的区别
  8. Factorials
  9. php中函数和方法的区别
  10. Android 网络框架 OKHttp3
  11. 用PHP判断是否闰年(正则匹配法)
  12. Python中使用operator模块实现对象的多级排序
  13. 1732157 - Collecting diagnosis information for SAP HANA [VIDEO]
  14. 10.21CRM项目(01)
  15. 关于linux下安装并打开网易云音乐——v 1.0.0
  16. Base64 转 图片
  17. python之模块datetime详解
  18. jsp学习小记
  19. 2018.06.30 BZOJ1857: [Scoi2010]传送带(三分套三分)
  20. 【数组】Jump Game

热门文章

  1. DNS服务器的原理
  2. Java-Android 之短信发送
  3. ab安装和使用
  4. HTML5+移动APP(2)
  5. eclipse alt + '/' not working.
  6. KAFKA分布式消息系统[转]
  7. AFNetworking自带的解析图片的方法
  8. Spring MVC中 controller方法返回值
  9. [LeetCode OJ] Distinct Subsequences
  10. 24种设计模式--工厂方法模式【Factory Method Pattern】