美文网首页
ASIHttpRequest中Block代码块的使用和注意事项

ASIHttpRequest中Block代码块的使用和注意事项

作者: 祥子_HelloWorld | 来源:发表于2019-08-05 00:03 被阅读0次

    使用ASIHttpRequest的setCompletionBlock、setFailedBlock时碰到一些诡异的内存泄漏和莫名其妙的行为(如:无法release对象)。

    1. 声明ASIHttpRequest时一定要使用__block关键字

    __block关键字告诉block不要retain request,这对于防止循环retain非常重要!!因为request总是会retain block

    2. 谨慎处理block与对象的关系

    当setCompletionBlock/setFailedBlock内部使用对象的instance var时,self会被retain(If you access an instance variable by reference, self is retained;)。所以在request结束前向对象发送release消息不会导致对象的释放(dealloc),亦即:该对象依然可进行所有操作,这将导致诸多你意想不到的结果。

    3. 解决第2点的问题

    3.1 仔细拿捏block与对象的关系 + 按值的方式访问instance var(If you access an instance variable by value, the variable is retained.)
    3.2 不使用block,而使用ASIHttpRequestDelegate

    4. 参考资料

    4.1 http://allseeing-i.com/ASIHTTPRequest/How-to-use - Using blocks
    4.2 Blocks Programming Topics - Object and Block Variables

    接口部分:
    //
    //  LYHASIRequestBlock.h
    //  ASIBlockTest
    //
    //  Created by Charles Leo on 14-7-23.
    //  Copyright (c) 2014年 Charles Leo. All rights reserved.
    //
     
    #import <Foundation/Foundation.h>
    #import "ASIHTTPRequest.h"
    #import "ASIFormDataRequest.h"
    typedef void (^RequestBlock) (void);
    @interface LYHASIRequestBlock : NSObject <ASIHTTPRequestDelegate>
    {
        ASIHTTPRequest * getRequest;
        ASIFormDataRequest * postRequest;
        NSURL * url;
        RequestBlock finishBlock;
        RequestBlock failBlock;
        RequestBlock startBlock;
        NSString * requestType;
    }
     
    //接收到的数据
    @property (strong,nonatomic) NSData * receiveData;
    //请求完成的block
    - (void)didFinishBlock:(RequestBlock)block;
    //请求失败的block
    - (void)didFailedBlock:(RequestBlock)block;
    //请求开始的block
    - (void)didStartBlock:(RequestBlock)block;
    //取消请求
    - (void)cancelRequst;
    //get请求方法
    - (void)getRequest:(NSString *)getUrl;
    //post请求方法
    - (void)postRequest:(NSString *)postUrl andKeys:(NSArray *)keyArray andValues:(NSArray *)valueArray;
    @end
    
    实现部分:
    //
    //  LYHASIRequestBlock.m
    //  ASIBlockTest
    //
    //  Created by Charles Leo on 14-7-23.
    //  Copyright (c) 2014年 Charles Leo. All rights reserved.
    //
     
    #import "LYHASIRequestBlock.h"
     
    @implementation LYHASIRequestBlock
     
    - (void)getRequest:(NSString *)getUrl
    {
        requestType = @"GET";
        getRequest  = [[ASIHTTPRequest alloc]initWithURL:[NSURL URLWithString:getUrl]];
        getRequest.delegate = self;
        getRequest.timeOutSeconds = 15;
        [getRequest startAsynchronous];
    }
    #pragma mark -GET请求的代理方法
    //开始请求
    - (void)requestStarted:(ASIHTTPRequest *)request
    {
        startBlock();
    }
    //请求完成
    - (void)requestFinished:(ASIHTTPRequest *)request
    {
        self.receiveData = request.responseData;
        finishBlock();
    }
    //请求失败
    - (void)requestFailed:(ASIHTTPRequest *)request
    {
        failBlock();
    }
    //post请求
    -(void)postRequest:(NSString *)postUrl andKeys:(NSArray *)keyArray andValues:(NSArray *)valueArray
    {
        postRequest = [[ASIFormDataRequest alloc]initWithURL:[NSURL URLWithString:postUrl]];
        postRequest.timeOutSeconds = 15;
        postRequest.delegate = self;
        for (int i = 0; i<keyArray.count; i++) {
            [postRequest setPostValue:[valueArray objectAtIndex:i] forKey:[keyArray objectAtIndex:i]];
        }
        [postRequest setDidFinishSelector:@selector(didFinishPostRequest:)];
        [postRequest setDidStartSelector:@selector(didStartPostRequest:)];
        [postRequest setDidFailSelector:@selector(didFailPostRequest:)];
        [postRequest startAsynchronous];
    }
     
    #pragma mark - POST请求的代理方法
    //请求开始
    - (void)didStartPostRequest:(ASIFormDataRequest *)request
    {
        startBlock();
    }
    //请求完成
    - (void)didFinishPostRequest:(ASIFormDataRequest *)request
    {
        finishBlock();
    }
    //请求失败
    - (void)didFailPostRequest:(ASIFormDataRequest *)request
    {
        failBlock();
    }
     
    //设置Blocks
    //设置开始块
    - (void)didStartBlock:(RequestBlock)block
    {
        [startBlock release];
        startBlock = [block copy];
    }
    //设置完成块
    -(void)didFinishBlock:(RequestBlock)block
    {
        [finishBlock release];
        finishBlock = [block copy];
    }
    //设置失败块
    -(void)didFailedBlock:(RequestBlock)block
    {
        [failBlock release];
        failBlock = [block copy];
    }
    //取消请求
    - (void)cancelRequst{
        if ([requestType isEqualToString:@"GET"])
        {
            [getRequest cancel];
        }
        else if([requestType isEqualToString:@"POST"])
        {
            [postRequest cancel];
        }
    }
     
    -(void)dealloc
    {
        [getRequest release];
        [postRequest release];
        [startBlock release];
        [finishBlock release];
        [failBlock release];
        [super dealloc];
    }
    @end
    

    参考:http://www.cocoachina.com/bbs/read.php?tid=95100
    http://code4app.com/snippets/one/%E7%94%A8Block%E5%B0%81%E8%A3%85ASIHttpRequest/5428f5b8933bf0bf118b51d8

    相关文章

      网友评论

          本文标题:ASIHttpRequest中Block代码块的使用和注意事项

          本文链接:https://www.haomeiwen.com/subject/tlojdctx.html