项目发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. N宫格

    <!doctype html> <html> <head> <meta charset="utf-8"> <meta name ...

  2. Delphi字符串处理函数

    1.Copy 功能说明:该函数用于从字符串中复制指定范围中的字符.该函数有3个参数.第一个参数是数据源(即被复制的字符串),第二个参数是从字符串某一处开始复制,第三个参数是要复制字符串的长度(即个数) ...

  3. SEO搜索引擎优化基础

    要如何提高自己网站的知名度,那必须了解一些SEO知识. 1.什么是搜索引擎 所谓的搜索引擎(Search  Engines)是一些能够主动搜索信息(搜索网页上的单词和简短的特定的内容描述)并将其自动索 ...

  4. 静态文本框控件的美化CStatic

    VC通用控件都是灰色,当对程序界面进行美化时,使用通用控件就和美化后的程序界面不搭配,在VB,C#中,可以很方便的更改控件背景颜色,但在VC中就不能,需要我们自己来完善这方面的功能.我在这只简单的介绍 ...

  5. APK无源码使用Robotium简单总结

    1.使用re-sign.jar对待测包进行重签名,并记录下包名和主Activity名. 2.在Eclipse中点击File-New-Other 选择Android下的Android Test Proj ...

  6. 前端应该掌握的CSS实现多列等高布局

    1.引言 我们在写页面的时候,有的时候会遇到多栏布局,每个栏目里面的内容有的时候可能不一样,这样就会导致每个栏目实际的高度也是不一样的,如果每个栏目有背景颜色的,就会导致每个栏目的底部是对不齐的,用户 ...

  7. Leetcode 532.数组中的K-diff数对

    数组中的K-diff数对 给定一个整数数组和一个整数 k, 你需要在数组里找到不同的 k-diff 数对.这里将 k-diff 数对定义为一个整数对 (i, j), 其中 i 和 j 都是数组中的数字 ...

  8. Java学习2

    final在修饰类时,并不限制用户修改对象包含的变量值,只是限制了对象的主转移,只能针对某一个对象进行操作,中途不可更改对象. 重写父类的方法 重写(Override)和重载(Overload)都是针 ...

  9. [c++面试准备]--vector对象是如何增长的

    参考资料:cpp primer 5th 背景: 为了支持快速的访问,vector/string将元素连续存储--每个元素都是紧挨着前一个元素存储. 如果我们向vector/string中添加新的元素, ...

  10. 【译】从现有的容器里创建新的Docker镜像

    如果你修改了一个容器的内容,你可以使用docker commit命令将现有的容器状态保存为一个镜像. 下面的例子展示了如何修改一个基于oraclelinux:6.6的容器使得其能够运行Apache H ...