zoukankan      html  css  js  c++  java
  • 由ASIHttpRequest里的block引发的思考

    项目发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相应的变量,我们要使用用弱引用修饰的变量

  • 相关阅读:
    【凡尘】---react-redux---【react】
    React生命周期详解
    写文章很难,ai自动生成文章为你来排忧
    怎么用ai智能写作【智媒ai伪原创】快速写文章?
    给大家介绍个Seo伪原创工具吧,可以免费用的哈
    自媒体文章难写,在线伪原创文章生成就简单了
    内容创作难吗 不妨试试智媒ai伪原创
    Ai伪原创工具,轻松几秒出爆文
    什么AI写作软件靠谱,好用?
    分享个免费伪原创工具 关键词自动生成文章
  • 原文地址:https://www.cnblogs.com/lisa090818/p/3171793.html
Copyright © 2011-2022 走看看