转载自: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. QC使用中问题点汇总

    QC 使用中问题点汇总,包括以下四个方面: 1.不兼容IE7,IE8的问题(服务器端设置) 2.无法在Win 7下正常下载页面(客户端设置) 3.在QC中填写中文内容后无法正常提交到数据库(客户端设置 ...

  2. eclipse使用外部maven时multiModuleProjectDirectory错误解决

    错误提醒: -Dmaven.multiModuleProjectDirectory system propery is not set. Check $M2_HOME environment vari ...

  3. SSH-KeyGen 的用法

    假设 A 为客户机器,B为目标机: 要达到的目的:A机器ssh登录B机器无需输入密码:加密方式选 rsa|dsa均可以,默认dsa 做法:1.登录A机器 2.ssh-keygen -t [rsa|ds ...

  4. DLL调试方法

    1.已经做好的dll不能设置:你可以用AfxMessageBox把信息打印出来.2.哪个地方调用的函数 把DLL重新编译一次 在把DLL放到工程里 从新添加一下 然后在你工程调用DLL内容的地方设置断 ...

  5. 微信支付坑:url未注册

    微信支付,报:url未注册 页面URL未注册 支付授权目录 这里很重要我就是在这里折腾了很久.怎么设置呢,首先要看你支付的当前页面URL 比如是:http://www.taidupa.com/wxpa ...

  6. CATransform3D的使用以及各个参数的含义

    1. 缩放 CABasicAnimation *theAnimation=[CABasicAnimation animationWithKeyPath:@"transform"]; ...

  7. 一个字符串搜索的Aho-Corasick算法

    Aho和Corasick对KMP算法(Knuth–Morris–Pratt algorithm)进行了改进,Aho-Corasick算法(Aho-Corasick algorithm)利用构建树,总时 ...

  8. [QML] Connections元素介绍

    一个Connections对象创建一个了一个QML信号的连接.在QML中,我们连接信号通常是用使用"on<Signal>"来处理的,如下所示: MouseArea { ...

  9. 得到root,并且获取密码

    第一次使用ubuntu的时候 先使用这个命令 sudo passwd root 然后就可以改密码了

  10. JS-将input输入框写入的小写字母全部转换成为大写字母的JS代码

    <input name="htmer" type="text" onkeyup="this.value=this.value.toUpperCa ...