ASIHTTPRequest足够了吗?

大家都知道ASIHTTPRequest系列的类很好用,功能很强大。但也像NSURLConnection一样,一个网络请求就需要实例化一个对象,而且无法避免重复请求的问题。

我个人不习惯用ASIHTTPRequest,因为它功能太强大了,函数太多了,而我们平时的项目仅仅是处理基于HTTP协议的网络交互,用ASIHTTPRequest未免太“奢侈”了。更重要的是,它并无法避免网络的重复请求的问题,而且无法控制网络请求数量,所以仅仅使用ASIHTTPRequest还不够。

事实上,用NSURLConnection足够了。下面是我写的封装

HTTPConnection.h

//// HTTPConnection.h// //// Created by Jianhong Yang on 12-1-3.// Copyright (c) 2012年 __MyCompanyName__. All rights reserved.//#import <Foundation/Foundation.h>@protocol HTTPConnectionDelegate;@interface HTTPConnection : NSObject {@private//int _numberOfURLConnection;int _maxNumberOfURLConnection;NSMutableArray *_marrayTaskDic;id <HTTPConnectionDelegate> _delegate;}@property (nonatomic, assign) int maxNumberOfURLConnection;@property (nonatomic, assign) id <HTTPConnectionDelegate> delegate;// 根据URL获取Web数据- (BOOL)requestWebDataWithURL:(NSString *)strURL andParam:(NSDictionary *)dicParam priority:(BOOL)priority;// 根据URLRequest获取Web数据- (BOOL)requestWebDataWithRequest:(NSURLRequest *)request andParam:(NSDictionary *)dicParam priority:(BOOL)priority;//取消网络请求- (BOOL)cancelRequest:(NSDictionary *)dicParam;//清空网络请求- (void)clearRequest;@end@protocol HTTPConnectionDelegate <NSObject>@optional// 网络数据下载失败- (void)httpConnect:(HTTPConnection *)httpConnect error:(NSError *)error with:(NSDictionary *)dicParam;// 服务器返回的HTTP信息头- (void)httpConnect:(HTTPConnection *)httpConnect receiveResponseWithStatusCode:(NSInteger)statusCode andAllHeaderFields:(NSDictionary *)dicAllHeaderFields with:(NSDictionary *)dicParam;// 服务器返回的部分数据- (void)httpConnect:(HTTPConnection *)httpConnect receiveData:(NSData *)data with:(NSDictionary *)dicParam;// 网络数据下载完成- (void)httpConnect:(HTTPConnection *)httpConnect finish:(NSData *)data with:(NSDictionary *)dicParam;@end#ifdef DEBUG#define HTTPLOG(fmt,…)NSLog((@"HTTP->%s(%d):"fmt),__PRETTY_FUNCTION__,__LINE__,##__VA_ARGS__)#else#define HTTPLOG(fmt,…)NSLog(fmt,##__VA_ARGS__)#endif

HTTPConnection.m

//// HTTPConnection.m// //// Created by Jianhong Yang on 12-1-3.// Copyright (c) 2012年 __MyCompanyName__. All rights reserved.//#import "HTTPConnection.h"#define MAXNUMBER_URLCONNECTION10#define TASKSTATUS_RUN@"Run"#define TASKSTATUS_WAIT@"Wait"@interface HTTPConnection (Private)- (void)startURLConnection;@end@implementation HTTPConnection@synthesize maxNumberOfURLConnection = _maxNumberOfURLConnection;@synthesize delegate = _delegate;- (id)init{self = [super init];if (self) {// Custom initialization._numberOfURLConnection = 0;_maxNumberOfURLConnection = MAXNUMBER_URLCONNECTION;_marrayTaskDic = [[NSMutableArray alloc] initWithCapacity:5];}return self;}- (void)dealloc{//清空任务[self clearRequest];//[_marrayTaskDic release];[super dealloc];}#pragma mark -#pragma mark Public// 根据URL获取Web数据- (BOOL)requestWebDataWithURL:(NSString *)strURL andParam:(NSDictionary *)dicParam priority:(BOOL)priority{if (nil == dicParam) {return NO;}NSURL *url = [NSURL URLWithString:strURL];NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];BOOL success = [self requestWebDataWithRequest:request andParam:dicParam priority:priority];[request release];return success;}// 根据URLRequest获取Web数据- (BOOL)requestWebDataWithRequest:(NSURLRequest *)request andParam:(NSDictionary *)dicParam priority:(BOOL)priority{if (nil == dicParam) {return NO;}//正在处理或等待处理的任务不再接收for (NSDictionary *dicTask in _marrayTaskDic) {//if ([dicParam isEqualToDictionary:[dicTask objectForKey:@"param"]]) {HTTPLOG(@"任务重复:%@", dicParam);//需优先处理且为等待状态if (priority && [[dicParam objectForKey:@"status"] isEqualToString:TASKSTATUS_WAIT]) {[dicTask retain];[_marrayTaskDic removeObject:dicTask];[_marrayTaskDic insertObject:dicTask atIndex:0];[dicTask release];}return NO;}}HTTPLOG(@"添加新任务,参数:%@", dicParam);NSMutableDictionary *mdicTask = [[NSMutableDictionary alloc] initWithCapacity:3];//设置数据缓存NSMutableData *mdataCache = [[NSMutableData alloc] init];[mdicTask setObject:mdataCache forKey:@"cache"];[mdataCache release];//参数[mdicTask setObject:dicParam forKey:@"param"];//状态[mdicTask setObject:TASKSTATUS_WAIT forKey:@"status"];//创建HTTP网络连接NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];[mdicTask setObject:urlConnection forKey:@"connect"];[urlConnection release];//保存到数组if (priority) {[_marrayTaskDic insertObject:mdicTask atIndex:0];}else {[_marrayTaskDic addObject:mdicTask];}[mdicTask release];[self startURLConnection];return YES;}// 取消网络请求- (BOOL)cancelRequest:(NSDictionary *)dicParam{if (nil == dicParam) {return NO;}//遍历所有任务for (int i = 0; i < _marrayTaskDic.count; i++) {//查看任务是否相同NSDictionary *dicTask = [_marrayTaskDic objectAtIndex:i];if ([dicParam isEqualToDictionary:[dicTask objectForKey:@"param"]]) {//取消网络请求NSURLConnection *connect = [dicTask objectForKey:@"connect"];//未启动的须先启动再取消,不然有内存泄露if ([TASKSTATUS_WAIT isEqualToString:[dicTask objectForKey:@"status"]]) {[connect start];}[connect cancel];//从任务队列中删除[_marrayTaskDic removeObjectAtIndex:i];_numberOfURLConnection -= 1;return YES;}}return NO;}// 清空网络请求- (void)clearRequest{//遍历所有任务for (NSDictionary *dicTask in _marrayTaskDic) {NSURLConnection *connect = [dicTask objectForKey:@"connect"];//未启动的须先启动再取消,不然有内存泄露if ([TASKSTATUS_WAIT isEqualToString:[dicTask objectForKey:@"status"]]) {[connect start];}[connect cancel];//_numberOfURLConnection -= 1;}//从任务队列中删除[_marrayTaskDic removeAllObjects];}// 获取已经下载到的数据- (void)loadReceivedDataOf:(NSDictionary *)dicParam into:(NSMutableData *)mdataReceived{for (NSDictionary *dicTask in _marrayTaskDic) {//找到相应的数据if ([dicParam isEqualToDictionary:[dicTask objectForKey:@"param"]]) {//取出已经下载到的数据NSData *data = [dicTask objectForKey:@"cache"];if (data.length > 0) {[mdataReceived setData:data];break;}}}}#pragma mark -#pragma mark NSURLConnectionDataDelegate- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{HTTPLOG(@"网络请求错误:%@", error);//找到当前失败的任务int indexTask = 0;NSDictionary *dicTask = nil;for (int i = 0; i < _marrayTaskDic.count; i++) {NSDictionary *dic = [_marrayTaskDic objectAtIndex:i];//找到网络连接相应的数据字典if ([dic objectForKey:@"connect"] == connection) {indexTask = i;dicTask = [dic retain];break;}}//删除失败的任务if (dicTask) {//删除_numberOfURLConnection -= 1;[_marrayTaskDic removeObjectAtIndex:indexTask];//启动新任务[self startURLConnection];//通知上层任务失败NSDictionary *dicParam = [dicTask objectForKey:@"param"];if ([_delegate respondsToSelector:@selector(httpConnect:error:with:)]) {[_delegate httpConnect:self error:error with:dicParam];}}[dicTask release];}- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{HTTPLOG(@"网络请求收到响应");//找到相应的任务NSDictionary *dicTask = nil;for (int i = 0; i < _marrayTaskDic.count; i++) {NSDictionary *dic = [_marrayTaskDic objectAtIndex:i];//找到网络连接相应的数据字典if ([dic objectForKey:@"connect"] == connection) {dicTask = dic;break;}}//if ([response isMemberOfClass:NSHTTPURLResponse.class]) {NSHTTPURLResponse *responseHTTP = (NSHTTPURLResponse *)response;NSUInteger statusCode = responseHTTP.statusCode;NSDictionary *dicAllHeaderFields = responseHTTP.allHeaderFields;NSDictionary *dicParam = [dicTask objectForKey:@"param"];//收到服务器返回的HTTP信息头SEL receiveResponse = @selector(httpConnect:receiveResponseWithStatusCode:andAllHeaderFields:with:);if ([self.delegate respondsToSelector:receiveResponse]) {[self.delegate httpConnect:self receiveResponseWithStatusCode:statusCodeandAllHeaderFields:dicAllHeaderFields with:dicParam];}}}- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{HTTPLOG(@"网络请求收到数据");//找到相应的任务NSDictionary *dicTask = nil;for (int i = 0; i < _marrayTaskDic.count; i++) {NSDictionary *dic = [_marrayTaskDic objectAtIndex:i];//找到网络连接相应的数据字典if ([dic objectForKey:@"connect"] == connection) {dicTask = dic;break;}}//if (dicTask) {//向缓存中添加数据NSMutableData *mdataCache = [dicTask objectForKey:@"cache"];[mdataCache appendData:data];NSDictionary *dicParam = [dicTask objectForKey:@"param"];HTTPLOG(@"该数据的参数:%@", dicParam);//收到部分数据if ([self.delegate respondsToSelector:@selector(httpConnect:receiveProgressChanged:with:)]) {[self.delegate httpConnect:self receiveProgressChanged:mdataCache.length with:dicParam];}}HTTPLOG(@"网络请求收到数据并处理完成");}- (void)connectionDidFinishLoading:(NSURLConnection *)connection{HTTPLOG(@"网络请求完成");//找到当前完成的任务int indexTask = 0;NSDictionary *dicTask = nil;for (int i = 0; i < _marrayTaskDic.count; i++) {NSDictionary *dic = [_marrayTaskDic objectAtIndex:i];//找到网络连接相应的数据字典if ([dic objectForKey:@"connect"] == connection) {indexTask = i;dicTask = [dic retain];break;}}//删除已经完成的任务if (dicTask) {//删除_numberOfURLConnection -= 1;[_marrayTaskDic removeObjectAtIndex:indexTask];//启动新任务[self startURLConnection];//通知上层完成任务NSData *dataCache = [dicTask objectForKey:@"cache"];NSDictionary *dicParam = [dicTask objectForKey:@"param"];if ([_delegate respondsToSelector:@selector(httpConnect:finish:with:)]) {[_delegate httpConnect:self finish:dataCache with:dicParam];}}[dicTask release];}#pragma mark – Private- (void)startURLConnection{if (_numberOfURLConnection < _maxNumberOfURLConnection) {if (_numberOfURLConnection < _marrayTaskDic.count) {//找到等待状态的任务for (NSMutableDictionary *mdicTask in _marrayTaskDic) {if ([TASKSTATUS_WAIT isEqualToString:[mdicTask objectForKey:@"status"]]) {//修改状态[mdicTask setObject:TASKSTATUS_RUN forKey:@"status"];//启动NSURLConnection *urlConnection = [mdicTask objectForKey:@"connect"];[urlConnection start];break;}}//_numberOfURLConnection += 1;}}HTTPLOG(@"正在处理的网络请求数:%i,,等待处理的网络请求:%i",_numberOfURLConnection, _marrayTaskDic.count-_numberOfURLConnection);}@end

我爱你….为了你的幸福,我愿意放弃一切—包括你。

ASIHTTPRequest足够了吗?

相关文章:

你感兴趣的文章:

标签云: