转载自:http://sherlockyao.com/blog/2015/08/08/weakself-and-strongself-in-blocks/

现在我们用 Objective-C 写代码时已经越来越多地用到了block,相比delegate的回调方式,block更直观易用。相信每个使用过block的人都遇到过block中使用self时需要weakself的情况,以下就是非常典型的一段代码:

1
2
3
4
5
__weak __typeof(self)weakSelf = self;
[self.context performBlock:^{
__strong __typeof(weakSelf)strongSelf = weakSelf;
[strongSelf doSomething];
}];

对于小白的我一般越到这种情况就是直接拷贝上面这个模板到需要的代码中去,而不知个中原委。但作为一个合格的程序员,是需要完完全全明白自己写的每一行代码是在做什么的,所以现在就简单说明一下这个 WeakSelf 和 StrongSelf 到底是什么。首先看下面这段代码:

1
2
3
[UIView animateWithDuration:0.2 animations:^{
self.myView.alpha = 1.0;
}];

在ARC环境下的,每个block在创建时,编译器会对里面用到的所有对象自动增加一个reference count,然后当block执行完毕时,再释放这些reference。针对上面的代码,在animations block执行期间,self(假设这里的self是个view controller)的引用数会被加1,执行完后再次减1。但这种情况下为什么我们一般不会去weakify self呢?因为这个block的生命周期是明确可知的,在这个block执行期间当前的view controller一般是不会被销毁的,所以不存在什么风险。现在我们看下面这个例子:

1
2
3
4
5
NSBlockOperation *op = [[[NSBlockOperation alloc] init] autorelease];
[op addExecutionBlock:^ {
[self doSomething];
[self doMoreThing];
}];

在这种情况下,我们并不知道这个execution block什么时候会执行完毕,所以很有可能发生的情况是,我在block还没执行完毕时就想销毁当前对象(比方说用户关闭了当前页面),这时就会因为block还对self有一个reference而没有立即销毁,这会引起很多问题,比方说你写在- (void)dealloc {}中的代码并不能马上得到执行。所以为了避免这种情况,我们会在block前加上__weak __typeof(self)weakSelf = self;的定义来使block对self获取一个弱引用(也就是refrence count不会加1)。

那block中的StrongSelf又是做什么的呢?还是上面的例子,当你加了WeakSelf后,block中的self随时都会有被释放的可能,所以会出现一种情况,在调用doSomething的时候self还存在,在doMoreThing的时候self就变成nil了,所以为了避免这种情况发生,我们会重新strongify self。一般情况下,我们都建议这么做,这没什么风险,除非你不关心self在执行过程中变成nil,或者你确定它不会变成nil(比方说所以block都在main thread执行)。

好了,简要的说明到此结束,想要详细了解的可以自行google,这类文章很多。前面代码中的WeakSelf、StrongSelf转换看起来很冗长,不利于阅读代码,下面介绍一个超好用的宏定义代码,它是这个开源库的一部分:libextobjc。把它加入到项目中后,就可以用以下如此简洁的格式来完成转换啦:

1
2
3
4
5
6
7
#import "EXTScope.h"

@weakify(self)
[self.context performBlock:^{
@strongify(self)
[self doSomething];
}];

WeakSelf和StrongSelf的更多相关文章

  1. 深入研究Block用weakSelf、strongSelf、@weakify、@strongify解决循环引用(下)

    深入研究Block捕获外部变量和__block实现原理 EOCNetworkFetcher.h typedef void (^EOCNetworkFetcherCompletionHandler)(N ...

  2. 深入研究Block用weakSelf、strongSelf、@weakify、@strongify解决循环引用(上)

    深入研究Block捕获外部变量和__block实现原理 前言 在上篇中,仔细分析了一下Block的实现原理以及__block捕获外部变量的原理.然而实际使用Block过程中,还是会遇到一些问题,比如R ...

  3. [HMLY]10.深入研究Block用weakSelf、strongSelf、@weakify、@strongify解决循环引用

    前言 在上篇中,仔细分析了一下Block的实现原理以及__block捕获外部变量的原理.然而实际使用Block过程中,还是会遇到一些问题,比如Retain Circle的问题. 目录 1.Retain ...

  4. weakSelf 和 strongSelf

    最近在看SDWebImage源码,碰到一些比较绕的问题,理解了很久,然后在网上查了些的资料,才算是有了一些理解.在此记录一下. 源码如下: block会copy要在block中使用的实变量,而copy ...

  5. weakSelf 和 strongSelf的区别和用处

    block会copy要在block中使用的实变量,而copy会是变量的retainCount + 1,如若在不注意很容易造成循环引用.而所谓的循环引用的本质就是,两个对象相互引用,从而造成对象不能正常 ...

  6. weakSelf 运用 strongSelf来解决block的循环引用

    SDWebImage 中有一段源码: #if SD_UIKIT Class UIApplicationClass = NSClassFromString(@"UIApplication&qu ...

  7. 关于iOS Block当中为什么要用weakSelf和strongSelf的思考

    场景:当你在某个界面请求网络数据的时候,用户不愿意等待点击了返回按钮,此时在Block当中用如下的方式使用weakSelf的话,有可能会奔溃(因为在并发编程的情况下,虽然在if判断的时候weaksel ...

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

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

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

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

随机推荐

  1. CentOS挂载硬盘

    1.查看当前硬盘使用状况: [root@gluster_node1 ~]# df -h 文件系统     容量 已用 可用 已用%% 挂载点 /dev/sda3 14G 2.4G 11G 19% / ...

  2. OA系统出现窗口拦截的解决办法

    我们使用oa时候,有时候会出现“你打开了窗口拦截功能”.如图 出现窗口被拦截主要有三种情况,分别是IE浏览器本身拦截功能.第三方插件(如百度工具栏.搜搜工具栏.谷歌工具栏等).第三方浏览器拦截功能(如 ...

  3. A Bit Fun

    A Bit Fun Time Limit : 5000/2500ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Sub ...

  4. if语句,函数function

    1.语句 一般分为顺序,分支和循环语句. if是分支语句 格式1:if(){}  若满足就进入花括号,若不满足就跳过 格式2:if(){}else(){}二选一.若if满足则else一定不执行,反之则 ...

  5. 其它网页可以上网,IE浏览器打不开网页的解决办法

    下面是自己引用别人的,作为自己的备注 昨天由于安装了多款软件,今天开机发现IE浏览器打不开了,废了些周折终于,修复了IE浏览器,现将ie浏览器打不开网页的经验分享给大家,希望此经验对于出现过此类情况的 ...

  6. vs2010使用C

    html, body { font-size: 15px; } body { font-family: Helvetica, "Hiragino Sans GB", 微软雅黑, & ...

  7. maven 国内镜像地址

    由于连接国外网站时网速特慢,为解决这个问题,os china 建立了一个maven 的私服.为了记忆,特将此记录. settings.xml 设置镜像方法步骤如下: 1. mirrors 设置 < ...

  8. TextUtils

    /** * 计算关键字在文本中出现的次数 * @param text * @param key * @return */ public static int count(String text, St ...

  9. 【贪心】 poj 1032 和为n的若干数最大乘积

    给出n,把n分解为若干不相同数之和,使之乘积最大.贪心,Discuss里面的思路:把n分解为从2开始的连续整数,如果有多,则从高位开始依次加1.如26,我们得到2+3+4+5+6,此时还剩余6(26- ...

  10. 【多重背包】 poj 2392

    转自:http://blog.csdn.net/wangjian8006 题目大意:有一头奶牛要上太空,他有很多种石头,每种石头的高度是hi,但是不能放到ai之上的高度,并且这种石头有ci个将这些石头 ...