转载,原文: 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。

参考

原文作者: 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

到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf的更多相关文章

  1. @weakify, @strongify ObjC的Block中使用weakSelf/strongSelf @weakify/@strongify

    首先要说说什么时候使用weakSelf和strongSelf. 下面引用一篇博客<到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf>的内容: Objec ...

  2. ObjC的Block中使用weakSelf/strongSelf @weakify/@strongify

    首先要说说什么时候使用weakSelf和strongSelf. 下面引用一篇博客<到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf>的内容: Objec ...

  3. model,map,MapAndVivew用于页面跳转时候使用的即跳转后才添加属性 这样再回调中无法使用 因为回调的前提是页面不调转;解决的方法是用responsewrite(普通的字符响应)

    model,map,MapAndVivew用于页面跳转时候使用的即跳转后才添加属性 这样再回调中无法使用 因为回调的前提是页面不调转:解决的方法是用responsewrite

  4. (转)linux sudo 重定向,实现只有系统管理员才有权限操作的文件中写入信息

    众所周知,使用 echo 并配合命令重定向是实现向文件中写入信息的快捷方式. 本文介绍如何将 echo 命令与 sudo 命令配合使用,实现向那些只有系统管理员才有权限操作的文件中写入信息.   比如 ...

  5. 关于PCB布线的顺序到底是怎样才合理?

    有人说先布好电源线和地线,让它们尽量靠近走,然后再考虑信号线:也有人说先布好关键的信号线,然后再走电源和地线:还有人说先布好电源线,再布信号线,地线最后布.到底怎么样才算好呢?或者说,一般应按照什么顺 ...

  6. 使用Reveal.app调试整个项目UI时间,增加LD指令 -Objc引起项目中多个静态库冲突问题

    今天接触到一个新的UI调试工具教程如下: iOS真机UI调试利器——Reveal 引入增加-ObjC -framework Reveal指令后,发现项目出现多重静态库冲突问题, 首先介绍一个指令: - ...

  7. 斗地主你什么时候才会托管?(.NET中的托管于非托管)

    文章部分引自<.NET4.0面向对象编程漫谈(基础篇)>第1章.NET面向对象编程基础(作者:金旭亮) 无意间看到一位四五岁左右小朋友在玩斗地主,总开始到结束,她一直都在使用“提示”(托管 ...

  8. substring()方法到底做了什么?不同版本的JDK中是否有区别?为什么?

      该文章是图说Java系列文章中的一篇 substring(int beginIndex, int endIndex)方法在jdk 6和jdk 7中的实现是不同的.了解他们的区别可以帮助你更好的使用 ...

  9. 在编译内核之前到底应该使用make mrproper,make distclean,make clean中的哪个命令呢?

    1. 先找到描述这三个命令的相关信息 在内核目录下使用make help命令可以获取相关信息,信息如下: Cleaning targets: clean - Remove most generated ...

随机推荐

  1. 关于IIS下字体跨域问题

    将网站的CSS与项目分离后报了一个错,是因为字体跨域的原因,查了一下资料. 解决方案如下: 1:打开访问的资源iis,在HTTP 响应表头中添加代码名称:Access-Control-Allow-Or ...

  2. [转]ExtJS3.0与KindEditor4.1.2整合

    原文地址:http://blog.csdn.net/resigshy/article/details/7937021 ExtJS与KindEditor整合的方式. /** * 将KindEditor4 ...

  3. 【C#】使用user32.dll的MessageBox弹窗消息

    要使用user32.dll的MessageBox弹窗消息,自然需要引入user32.dll到项目中. 一个最简单的实例如下: using System; using System.Runtime.In ...

  4. 【Unity笔记】Terrain地形制作坍塌/深坑

    Unity的Terrain组件在[set the terrain height]分页下,height高度为0时,可理解为该地形的海平面高度,此时就不能地形下榻.把height调到100,点击[flat ...

  5. 【转】使用scipy进行层次聚类和k-means聚类

    scipy cluster库简介 scipy.cluster是scipy下的一个做聚类的package, 共包含了两类聚类方法: 1. 矢量量化(scipy.cluster.vq):支持vector ...

  6. [Issue]Ubuntu 16.04 ssh: sign_and_send_pubkey: signing failed: agent refused operation

    解决:https://askubuntu.com/questions/762541/ubuntu-16-04-ssh-sign-and-send-pubkey-signing-failed-agent ...

  7. sc58x config

    addip=set bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0:off ...

  8. Extjs4.x Ext.tree.Panel 过滤Filter以及trigger field的使用

    Extjs4.x中已经取消了组件Ext.Tree.TreeFilter功能,却掉了树形结构的过滤功能,要实现该功能只能自己写了. Tree节点筛选UI很简单,一个Tbar,一个trigger即可解决问 ...

  9. .net 4中使用 dynamic,将json字符串转成对象的 万能方法。

    在.net 4中增加了对弱类型的支持.为和弱类型的对象进行数据交换提供了方法.我们常常会遇到将json字符串转成对象的情景,虽然可以使用 JavaScriptSerializer 或者 DataCon ...

  10. mysql中varbinary、binary、char、varchar异同

    binary 与 varbinary 类型和char与varchar类型是相似的,只是他们存储的是二进制数据,也就是说他们是包含字节流而不是字符流,他们有二进制字符的集合和顺序,他们的对比,排序是基于 ...