转载出处:http://hi.baidu.com/hehejuju2011/item/831bcb594e0a638009be17bf
ASINetworkQueue是NSOperationQueue的子类,提供更高级的特性(ASINetworkQueue的代理函数):
requestDidStartSelector
当一个request开始执行时,这个代理函数会被调用。
requestDidReceiveResponseHeadersSelector
当队列中的request收到服务器返回的头信息时,这个代理函数会被调用。对于下载很大的文件,这个通常比整个request的完成要早。
requestDidFinishSelector
当每个request完成时,这个代理函数会被调用。
requestDidFailSelector
当每个request失败时,这个代理函数会被调用。
queueDidFinishSelector
当队列完成(无论request失败还是成功)时,这个代理函数会被调用。
ASINetworkQueues与NSOperationQueues稍有不同,加入队列的request不会立即开始执行。如果队列打开了进度开关,那么队列开始时,会先对所有GET型request进行一次HEAD请求,获得总下载大小,然后真正的request才被执行。
向一个已经开始进行的ASINetworkQueue 加入request会怎样?
如果你使用ASINetworkQueue来跟踪若干request的进度,只有当新的request开始执行时,总进度才会进行自适应调整(向后移动)。ASINetworkQueue不会为队列开始后才加入的request进行HEAD请求,所以如果你一次向一个正在执行的队列加入很多request,那么总进度不会立即被更新。
如果队列已经开始了,不需要再次调用[queue go]。
当ASINetworkQueue中的一个request失败时,默认情况下,ASINetworkQueue会取消所有其他的request。要禁用这个特性,设置 [queue setShouldCancelAllRequestsOnFailure:NO]。
ASINetworkQueues只可以执行ASIHTTPRequest操作,二不可以用于通用操作。试图加入一个不是ASIHTTPRequest的NSOperation将会导致抛出错误。
例子1:
正确使用:
imgDataDownLoadQueue = [[ASINetworkQueue alloc] init];
[imgDataDownLoadQueue setShouldCancelAllRequestsOnFailure:NO];
[imgDataDownLoadQueue setDelegate:self];
[imgDataDownLoadQueue setRequestDidFailSelector:@selector(imgDataRequestFail:)];
[imgDataDownLoadQueue setRequestDidFinishSelector:@selector(imgDataRequestFinish:)];
[imgDataDownLoadQueue setQueueDidFinishSelector:@selector(imgDataQueueDidFinish:)];
for(int i=0; i<[imgDatasToLoadArray count]; i++)
{
ASIHTTPRequest* imgRq = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:[[imgDatasToLoadArray objectAtIndex:i] objectForKey:@"imgurl"]]];
NSString* value[2];
NSString* key[2];
value[0] = [[imgDatasToLoadArray objectAtIndex:i] objectForKey:@"imgtime"];
value[1] = [[imgDatasToLoadArray objectAtIndex:i] objectForKey:@"index"];
key[0] = @"imgtime";
key[1] = @"index";
imgRq.userInfo = [NSDictionary dictionaryWithObjects:value forKeys:key count:2];
[imgDataDownLoadQueue addOperation:imgRq];
}
[imgDataDownLoadQueue go];
//例子2
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
downLoadQueue=[[ASINetworkQueue alloc] init];
NSMutableArray *mutArr=[[NSMutableArray alloc] init];
NSString *str1=@"http://182.18.27.12:8022//pagess/admin/upload/20120326150820874.jpg";
NSString *str2=@"http://182.18.27.12:8022//pagess/admin/uploadaa/20120326150901644.jpg";
NSString *str3=@"http://182.18.27.12:8022//pagess/admin/upload/20120326150951908.jpg";
NSString *str4=@"http://182.18.27.12:8022//pagess/admin/upload/20120328140917352.jpg";
[mutArr addObject:str1];
[mutArr addObject:str2];
[mutArr addObject:str3];
[mutArr addObject:str4];
for (int i=0; i<[mutArr count]; i++) {
[downLoadQueue addOperation:[self downLoadImageWithURLStr:[mutArr objectAtIndex:i]]];
[downLoadQueue go];
}
}
-(ASIHTTPRequest *)downLoadImageWithURLStr:(NSString *)urlStr{
ASIHTTPRequest *request=[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:urlStr]];
[request setDownloadDestinationPath:[[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] stringByAppendingPathComponent:[NSString stringWithFormat:@"%d",i]]];
NSDictionary *dic=[NSDictionary dictionaryWithObject:[NSString stringWithFormat:@"%i",i]
forKey:@"httpRequstID"];
[request setUserInfo:dic];
UIProgressView *progressView;
switch (i) {
case 0:
progressView=self.gressView1;
break;
case 1:
progressView=self.gressView2;
break;
case 2:
progressView=self.gressView3;
break;
case 3:
progressView=self.gressView4;
break;
default:
break;
}
[request setDownloadProgressDelegate:progressView];
[request setDelegate:self];
++i;
return [request autorelease];
}
-(void) requestFinished:(ASIHTTPRequest *)request{
NSLog(@"%@",[request downloadDestinationPath]);
UIImage *image = [UIImage imageWithContentsOfFile:[request downloadDestinationPath]];
NSString *requstFlagStr= [request.userInfo objectForKey:@"httpRequstID"];
NSLog(@"%@",requstFlagStr);
if ([requstFlagStr isEqualToString:@"0"]) {
[self.imageView1 setImage:image];
}else if([requstFlagStr isEqualToString:@"1"]){
[self.imageView2 setImage:image];
}else if([requstFlagStr isEqualToString:@"2"]){
[self.imageView3 setImage:image];
}else if([requstFlagStr isEqualToString:@"3"]){
[self.imageView4 setImage:image];
}
}
- (void)requestFailed:(ASIHTTPRequest *)request{
NSLog(@"%@",[request responseString]);
}
NSURL *url=[[NSURL alloc] initWithString:@"http://www.baidu.com"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:@"Ben" forKey:@"first_name"];
[request setPostValue:@"Copsey" forKey:@"last_name"];
[request setFile:@"/Users/ben/Desktop/ben.jpg" forKey:@"photo"];
[request addData:imageData withFileName:@"george.jpg" andContentType:@"image/jpeg" forKey:@"photos"];
例子3:
#import “ASIHTTPRequest.h”
#import “ASINetworkQueue.h”
#import “NSNumber+Message.h”
#import “NSString+URLEncoding.h”
@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UIImageView *imageView1;
@property (weak, nonatomic) IBOutlet UIImageView *imageView2;
@property (strong) ASINetworkQueue *networkQueue;
- (IBAction)onClick:(id)sender;
@end
我 们需要引入ASI框架的两个头文件ASIHTTPRequest.h和ASINetworkQueue.h。其中imageView1和 imageView2是与画面对应的两个图片视图控件。还定义了ASINetworkQueue 类型的networkQueue属性。我们直接看看主视图控制器ViewController.m中点击GO按钮调用方法,代码如下:
- (IBAction)onClick:(id)sender {
if (!_networkQueue) {
_networkQueue = [[ASINetworkQueue alloc] init]; ①
}
// 停止以前的队列
[_networkQueue cancelAllOperations]; ②
// 创建ASI队列
[_networkQueue setDelegate:self];
[_networkQueue setRequestDidFinishSelector:@selector(requestFinished:)]; ③
[_networkQueue setRequestDidFailSelector:@selector(requestFailed:)]; ④
[_networkQueue setQueueDidFinishSelector:@selector(queueFinished:)]; ⑤
for (int i=1; i<3; i++) {
NSString *strURL = [[NSString alloc] initWithFormat:
@”http://iosbook3/download.php?email=%@&FileName=test%i.jpg”,
@”<你的iosbook1.com用户邮箱>”,i];
NSURL *url = [NSURL URLWithString:[strURL URLEncodedString]];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
request.tag = i; ⑥
[_networkQueue addOperation:request]; ⑦
}
[_networkQueue go]; ⑧
}
我们再看看它们的回调方法,代码:
复制代码
- (void)requestFinished:(ASIHTTPRequest *)request
{
NSData *data = [request responseData];
NSError *eror;
NSDictionary *resDict = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments error:&eror];
if (!resDict) {
UIImage *img = [UIImage imageWithData:data];
if (request.tag ==1) { ①
_imageView1.image = img;
} else {
_imageView2.image = img;
}
} else {
NSNumber *resultCodeObj = [resDict objectForKey:@"ResultCode"];
NSString *errorStr = [resultCodeObj errorMessage];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@”错误信息”
message:errorStr
delegate:nil
cancelButtonTitle:@”OK”
otherButtonTitles: nil];
[alertView show];
}
if ([_networkQueue requestsCount] == 0) { ②
[self setNetworkQueue:nil];
}
NSLog(@”请求成功”);
}
- (void)requestFailed:(ASIHTTPRequest *)request ③
{
NSError *error = [request error];
NSLog(@”%@”,[error localizedDescription]);
if ([_networkQueue requestsCount] == 0) {
[self setNetworkQueue:nil];
}
NSLog(@”请求失败”);
}
- (void)queueFinished:(ASIHTTPRequest *)request ④
{
if ([_networkQueue requestsCount] == 0) {
[self setNetworkQueue:nil];
}
NSLog(@”队列完成”);
}
requestFinished: 方法是请求对象成功回调方法,因此有两个请求对象它会被调用两次,在第①行代码中我们根据GO按钮点击事件设定的 请求对象的tag属性,来判断是哪个请求对象的回调。进而加载到显示不同的图片视图。第②代码[_networkQueue requestsCount]可以判断队列中请求对象的个数。