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

  • 相关阅读:
    NAIPC 2019-It’s a Mod, Mod, Mod, Mod World(类欧几里德模板)
    BAPC 2018 Preliminaries-Isomorphic Inversion(字符串哈希)
    Cubemx 生成工程代码失败的原因
    共生滤波器相关论文分析
    西瓜书6.2 matlab的libsvm使用
    西瓜书4.4 基于基尼指数选择划分的决策树 预剪枝与后剪枝
    西瓜书4.3 编写过程 决策树
    西瓜书 5.5 编写过程(标准BP与累计BP)
    西瓜书3.4 解题报告(python 多分类学习 十折交叉法)
    西瓜书3.3 尝试解题(python)对率回归 极大似然估计
  • 原文地址:https://www.cnblogs.com/lisa090818/p/3171793.html
Copyright © 2011-2022 走看看