软件发布| 专题库| 优优资讯| 苹果专区| 安卓专区| 软件下载| 首页
优优资讯 电脑教程 安卓教程 安卓攻略 苹果教程 苹果攻略 新闻资讯

iOS开发:ASIHttpRequest创建和执行request

时间:2015-09-22 来源:本站整理 我要评论

  本文为大家介绍了iOS开发中ASIHttpRequest如何创建和执行request,其中包括同步请求,异步请求,使用Block,使用队列,取消异步请求等等内容。
 
  创建NSOperationQueue,这个Cocoa架构的执行任务(NSOperation)的任务队列。我们通过ASIHTTPRequest.h的源码可以看到,此类本身就是一个NSOperation的子类。也就是说它可以直接被放到任务队列中并被执行。
 
  同步请求
 
  同步请求会在当前线程中执行,使用error属性来检查结束状态(要下载大文件,则需要设定downloadDestinationPath来保存文件到本地):
 
  - (IBAction)grabURL:(id)sender
  {
  NSURL *url = [NSURL URLWithString:@"http://www.dreamingwish.com"];
  ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
  [request startSynchronous];
  NSError *error = [request error];
  if (!error) {
  NSString *response = [request responseString];
  }
  }
 
  同步请求会阻塞主线程的执行,这导致用户界面不响应用户操作,任何动画都会停止渲染。
 
  异步请求
 
  下面是最简单的异步请求方法,这个request会在全局的NSOperationQueue中执行,若要进行更复杂的操作,我们需要自己创建NSOperationQueue或者ASINetworkQueue,后面会讲到。
 
  - (IBAction)grabURLInBackground:(id)sender
  {
  NSURL *url = [NSURL URLWithString:@"http://www.dreamingwish.com"];
  ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
  [request setDelegate:self];
  [request startAsynchronous];
  }
  - (void)requestFinished:(ASIHTTPRequest *)request
  {
  // Use when fetching text data
  NSString *responseString = [request responseString];
  // Use when fetching binary data
  NSData *responseData = [request responseData];
  }
  - (void)requestFailed:(ASIHTTPRequest *)request
  {
  NSError *error = [request error];
  }
 
  使用block
 
  在平台支持情况下,ASIHTTPRequest1.8以上支持block。
 
  - (IBAction)grabURLInBackground:(id)sender
  {
  NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
  __block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
  [request setCompletionBlock:^{
  // Use when fetching text data
  NSString *responseString = [request responseString];
  // Use when fetching binary data
  NSData *responseData = [request responseData];
  }];
  [request setFailedBlock:^{
  NSError *error = [request error];
  }];
  [request startAsynchronous];
  }
 
  注意,声明request时要使用__block修饰符,这是为了告诉block不要retain request,以免出现retain循环,因为request是会retain block的。
 
  使用队列
 
  创建NSOperationQueue或者ASINetworkQueue队列,我们还可以设定最大并发连接数:maxConcurrentOperationCount
 
  - (IBAction)grabURLInTheBackground:(id)sender
  {
  if (![self queue]) {
  [self setQueue:[[[NSOperationQueue alloc] init] autorelease]];
  [self queue].maxConcurrentOperationCount = 4;
  }
  NSURL *url = [NSURL URLWithString:@"http://www.dreamingwish.com"];
  ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
  [request setDelegate:self];
  [request setDidFinishSelector:@selector(requestDone:)];
  [request setDidFailSelector:@selector(requestWentWrong:)];
  [[self queue] addOperation:request]; //queue is an NSOperationQueue
  }
  - (void)requestDone:(ASIHTTPRequest *)request
  {
  NSString *response = [request responseString];
  }
  - (void)requestWentWrong:(ASIHTTPRequest *)request
  {
  NSError *error = [request error];
  }
 
  如果不设定selector,那么系统会使用默认的requestFinished: 和 requestFailed:方法
 
  如果需要对队列里面的每个request进行区分,那么可以设定request的userInfo属性,它是个NSDictionary,或者更简单的方法是设定每个request的tag属性,这两个属性都不会被发送到服务器。
 
  不要使用request的URL来区分每个request,因为URL可能会改变(例如重定向),如果需要使用request的URL,使用[request originalURL],这个将永远返回第一个url。
 
  对于ASINetworkQueue
 
  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将会导致抛出错误。
 
  取消异步请求
 
  取消一个异步请求(无论request是由[request startAsynchronous]开始的还是从你创建的队列中开始的),使用[request cancel]即可。注意同步请求不可以被取消。
 
  注意,如果你取消了一个request,那么这个request将会被视为请求失败,并且request的代理或者队列的代理的失败代理函数将被调用。如果你不想让代理函数被调用,那么将delegate设置为nil,或者使用clearDelegatesAndCancel方法来取消request。
 
  clearDelegatesAndCancel 将会首先清除所有的代理和block。
 
  当使用ASINetworkQueue时,如果取消了队列中的一个request,那么队列中其他所有request都会被取消,可以设置shouldCancelAllRequestsOnFailure的值为NO来避免这个现象。
 
  安全地控制delegate防止request完成之前代理被释放
 
  request并不retain它们的代理,所以有可能你已经释放了代理,而之后request完成了,这将会引起崩溃。大多数情况下,如果你的代理即将被释放,你一定也希望取消所有request,因为你已经不再关心它们的返回情况了。如此做:
 
  // 代理类的dealloc函数
  - (void)dealloc
  {
  [request clearDelegatesAndCancel];
  [request release];
  ...
  [super dealloc];
  }
 

用户评论

(已有0条评论)
表情
注:您的评论需要经过审核才能显示哦,请文明发言!
还没有评论,快来抢沙发吧!
快速检索
0-9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z