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

本文介绍使用ASIHttpRequest结合Block时应注意的内存管理问题,包括如何避免循环引用和对象释放的注意事项,并提供了一种利用ASIHttpRequestDelegate替代Block的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用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 = 1 5 ;
     [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 = 1 5 ;
     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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值