项目发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. 使用WMI Filter 实现组策略的筛选!

    今天接到一个客户的一个问题,提到需要分系统版本分发相应的MSI程序.比如简体版接受简体版的分发程序,繁体版接受繁体版的分发程序!这个建立组策略的不同版本分发本身不会太难,我们只需要建立两个不同组策略分 ...

  2. 15、响应式布局和BootStrap 全局CSS样式知识点总结-part2

    1.表格 <div class="container"> <table class="table "> <thead> &l ...

  3. 非旋Treap总结 : 快过Splay 好用过传统Treap

    非旋$Treap$ 其高级名字叫$Fhq\ Treap$,既然叫$Treap$,它一定满足了$Treap$的性质(虽然可能来看这篇的人一定知道$Treap$,但我还是多说几句:$Fhp\ Treap$ ...

  4. 精通CSS高级Web标准解决方案(5、对列表应用样式和创建导航条)

    5.1基本样式列表 去掉列表的默认样式: ul{ margin:; padding:; list-style-type:none; } 添加定制的符号,在列表左边添加填充,为符号留出空间,然后将符号图 ...

  5. js后台提交成功后 关闭当前页 并刷新父窗体(转)

    原文地址:http://www.cnblogs.com/chenghu/p/3696433.html 后台提交成功后 关闭当前页 并刷新父窗体 this.ClientScript.RegisterSt ...

  6. Android之操作相册

    获取手机中的图片的绝对路径并且区分出每个文件夹下的路径: 存放图片绝对路径的文件夹的名字和存放绝对路径的List 实体类如下: import java.util.ArrayList; import j ...

  7. UVALive 5987

    求第n个数,该数满足至少由3个不同的素数的乘机组成 #include #include #include #include #include using namespace std; int prim ...

  8. 解决报错DEFAULT_INCOMPATIBLE_IMPROVEMENTS

    freemarker整合springMVC报错如下:警告: Exception encountered during context initialization - cancelling refre ...

  9. A.Equals(B)和A==B的区别

    Equals 和 == 都是用于比较. 如果a和b都是值类型,则a.Equals(b) 和 a == b 结果相同,但是在引用类型是它们的行为是不同的: string a = new string(n ...

  10. Gym 100971B 水&愚

    Description standard input/output Announcement   Statements A permutation of n numbers is a sequence ...