项目发http请求,现在一般的都是用的第三方开源库,当然发异步请求时我们也会写几个回调函数来进行请求返回时的处理。不过前段时间看一个朋友写的代码,里面很用block简单的实现了回调相关的部分。比如:

01 self.request=[ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]];
02 [_request setRequestMethod:@"GET"];
03  
04 [_request setCompletionBlock:^{
05      
06     _mobileField.enabled= YES;
07     _nextStepBtn.enabled = YES;
08     NSInteger statusCode = [_request responseStatusCode];
09     NSString *result = [_request responseString];
10 }];

看后感觉非常的方便与简单,但是使用Instruments跑的时候老是有内存泄漏的问题。后来查找一翻,I find out the reason;
原来block中调用了self或者self的成员变量,block就retain了self,而self也retain block,所以self和block都无法释放,最终形成cycle。
正确的写法如下:

01     self.request=[ASIHTTPRequest requestWithURL:[NSURL URLWithString:url]];
02     [_request setRequestMethod:@"GET"];
03     __unsafe_unretained ASIHTTPRequest *_requestCopy = _request;
04     __unsafe_unretained RegistUserViewController *this = self;
05     [_request setCompletionBlock:^{
06          
07         this.mobileField.enabled= YES;
08         this.nextStepBtn.enabled = YES;
09         NSInteger statusCode = [_requestCopy responseStatusCode];
10         NSString *result = [_requestCopy responseString];
11 }];

注意其中的__unsafe_unretained关键词,这个就是让block对所修饰的变量使用弱引用,也就ARC中的__weak。这样修饰的变量就不会被retain。

还有一种是用__block关键词的写法,也是官方文档中的写法(http://allseeing-i.com/ASIHTTPRequest/How-to-use);

01 - (IBAction)grabURLInBackground:(id)sender
02 {
03    NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
04    __block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
05    [request setCompletionBlock:^{
06       // Use when fetching text data
07       NSString *responseString = [request responseString];
08   
09       // Use when fetching binary data
10       NSData *responseData = [request responseData];
11    }];
12    [request setFailedBlock:^{
13       NSError *error = [request error];
14    }];
15    [request startAsynchronous];
16 }

还有一种将self改成弱引用的写法是
__block typeof(self) bself = self;

关于block中的成员变量的调用方法也要注意下面两点:
对于property就用点操作符 bself.xxx
对于非property的成员变量就用->操作符 bself->xxx

最后总结,所有的这些都是围绕一点,block会retain相应的变量,我们要使用用弱引用修饰的变量

由ASIHttpRequest里的block引发的思考的更多相关文章

  1. Spring之LoadTimeWeaver——一个需求引发的思考---转

    原文地址:http://www.myexception.cn/software-architecture-design/602651.html Spring之LoadTimeWeaver——一个需求引 ...

  2. class_copyIvarList方法获取实例变量问题引发的思考

    在runtime.h中,你可以通过其中的一个方法来获取实例变量,那就是class_copyIvarList方法,具体的实现如下: - (NSArray *)ivarArray:(Class)cls { ...

  3. 由一个emoji引发的思考

    由一个emoji引发的思考 从毕业以来,基本就一直在做移动端,但是一直就关于移动端的开发,各种适配问题的解决,在日常搬砖中处理了就过了,也没有把东西都沉淀下来,觉得甚是寒颜.现就一个小bug,让我们来 ...

  4. 一次composer错误使用引发的思考

    一次composer错误使用引发的思考 这个思考源自于一个事故.让我对版本依赖重新思考了一下. 事故现象 一个线上的管理后台,一个使用laravel搭建的管理后台,之前在线上跑的好好的,今天comop ...

  5. 一个ScheduledExecutorService启动的Java线程无故挂掉引发的思考

    2018年12月12日18:44:53 一个ScheduledExecutorService启动的Java线程无故挂掉引发的思考 案件现场 不久前,在开发改造公司一个端到端监控日志系统的时候,出现了一 ...

  6. FastAdmin Bootstrap-Table 关于客户端模式(由 计算所有页的的总数引发的思考)

    Bootstrap-Table 关于客户端模式(由 计算所有页的的总数引发的思考) 昨天群里有小伙伴询问 Bootstrap-Table 有没有计算所有页的总数. [吐槽]★隔壁老王-杭州 @F4NN ...

  7. 由C# dynamic是否装箱引发的思考

    前言 前几天在技术群里看到有同学在讨论关于dynamic是否会存在装箱拆箱的问题,我当时第一想法是"会".至于为啥会有很多人有这种疑问,主要是因为觉得dynamic可能是因为有点特 ...

  8. 测试杂谈——一条SQL引发的思考(二)

    在前段时间,曾写过一篇关于SQL问题的文章,测试杂谈--一条SQL引发的思考(一). 今天这篇,算是个问题记录吧,问题并不复杂,但对于测试同学而言,确实是个需要关注的点. 问题分析 最近在日常工作中, ...

  9. 由SecureCRT引发的思考和学习

    由SecureCRT引发的思考和学习 http://mp.weixin.qq.com/s?__biz=MzAxOTAzMDEwMA==&mid=2652500597&idx=1& ...

随机推荐

  1. Event log c++ sample.

    1. Init regedit. bool InitLog( TCHAR *logName, TCHAR *sourceName, TCHAR *MessageDllName ) { // This ...

  2. laravel5.2总结--序列化

    序列化 构建Json格式的API接口时,经常需要转换 '模型' 和 '关联关系' 为数组或者JSON. 1>转换模型为数组:   $user = App\User::with('roles')- ...

  3. mac攻略(九) -- ssh工具secureCRT

    mac ssh 客户端 : 本身mac直接使用终端来ssh连接就很方便,但是使用过程中随着远程服务器的增多和zsh和远程服务器编码不同产生了乱码,决定安装一款ssh终端软件,以下方法亲测可用,感谢提供 ...

  4. 报错: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException: An attempt by a client to checkout a Connection has timed out. 数据库连接超时

    解决方法一: [oracle@data ~]$ sqlplus / as sysdba——连接到数据库 SQL*Plus: Release 11.2.0.4.0 Production on Mon M ...

  5. Python+selenium(警告框处理)

    在Webdriver中处理JavaScript生成的alert.confirm.prompt,使用switch_to_alert()方法定位到alert.confirm.prompt,然后进行如下操作 ...

  6. opendatasource问题

    EXEC sp_configure 'show advanced options', 1 GO RECONFIGURE GO EXEC sp_configure 'Ad Hoc Distributed ...

  7. Python之协程的实现

    1.Python里面一般用gevent实现协程协程, 而协程就是在等待的时候切换去做别的操作,相当于将一个线程分块,充分利用资源 (1)低级版协程的实现 import gevent def test1 ...

  8. AngularJs 特性 之 模块化

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 【bzoj1221】[HNOI2001] 软件开发 费用流

    题目描述 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员每天提供一块消 ...

  10. [LOJ#2329]「清华集训 2017」我的生命已如风中残烛

    [LOJ#2329]「清华集训 2017」我的生命已如风中残烛 试题描述 九条可怜是一个贪玩的女孩子. 这天她在一堵墙钉了 \(n\) 个钉子,第 \(i\) 个钉子的坐标是 \((x_i,y_i)\ ...