ASINetworkQueue讲解

这个例子做相同的事情,但是这次我们为我们的请求创建一个NSOperationQueue。

使用你创建的NSOperationQueue(或者下面讲到的ASINetworkQueue),就可以对异步请求进行更多的控制。当使用一个queue的时候,只有一定数量的请求同时运行。如果你向一个队列中添加的请求多于属性maxConcurrentOperationCount指定的数量,多出的请求会等到其它的请求结束才能开始运行。

       - (IBAction)grabURLInTheBackground:(id)sender

       {

              if (![self queue]) {

                    [self setQueue:[[[NSOperationQueue alloc] init] autorelease]];

              }

              NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];

              ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];

              [request setDelegate:self];

              [request setDidFinishSelector:@selector(requestDone:)];

              [request setDidFailSelector:@selector(requestWentWrong:)];

              [[self queue] addOperation:request]; //queue is anNSOperationQueue

       }

       - (void)requestDone:(ASIHTTPRequest *)request

       {

              NSString *response = [request responseString];

        }

        - (void)requestWentWrong:(ASIHTTPRequest *)request

       {

              NSError *error = [request error];

       }

       在上面的例子中,’queue’是我们控制器的一个retainedNSOperationQueue属性。

       我们设置自定义的selectors,它们会在请求成功或失败后被调用。如果你不设置这些,默认的(requestFinished:和requestFailed:)会向前面的例子中那样被使用。

1.5 在代理方法中处理多个请求的成功和失败状态

如果你需要处理多个请求的成功和失败的状态,你可以有几种选择:

1.           如果你的请求是相同的类型,但是你想区分它们,你可以用自定义的数据设置每个请求的字典类型的属性userInfo,这样你就可以在请求的成功或失败的代理方法中读取设置的值,通过这些值区分不同的请求。更简单的一种方式,你可以设置请求的tag属性。这两种属性是提供给你使用的,它们不会被发送到服务端。

2.           对于每个请求,如果你需要一个完全不同的方式处理成功或失败的返回结果,你可以针对每个请求设置不同的setDidFinishSelector和setDidFailSelector。

3.           对于更复杂的情况,或者说如果你想在后台解析返回结果,可以这堆每种类型的请求,创建ASIHttpRequest的一个最小子类,并且重载方法requestFinished:和failWithError:。

注意:最好避免在代理方法中通过请求的URL区分不同的请求,因为当重定向的时候URL属性会改变。如果你真的想使用请求的URL,可以使用[request originalURL],这样总会是第一次请求的url。

1.6 关于ASINetworkQueues

    ASINetworkQueue是类NSOperationQueue的子类,它提供了一些额外的功能。

它主要的目的是使你能够跟踪整个queue的上传和下载的过程。

另外,ASINetworkQueues提供了一些额外的代理方法:

l   requestDidStartSelector

    队列中的每个请求开始执行的时候调用这个方法。你可以使用它作为”设置你添加到queue的请求的代理方法并指定这个请求的didStartSelector”的替代方法。

l   requestDidReceiveResponseHeaderSeletor

当队列中的一个请求收到服务端回复的请求头时被调用。对于大数据量的下载,这个会在真正的下载完成之前被调用。你可以使用这个作为“设置你添加到queue中的请求的代理并且指定请求的didFailSelector”的一个替代方案。

l   requestDidFinishSelector

    当队列中一个请求成功时被调用。你可以使用这个作为“设置你添加到队列中请求的代理并指定一个didFinishSelector”的一个替代方案。

l    requestDidFailSelector

    当队列中一个请求失败时被调用。你可以使用这个作为“设置你添加到队列中请求的代理并指定一个didFailSelector”的一个替代方案。

l     queueDidFinishSelector

当整个队列完成时才被调用,不管单个的请求是成功还是失败。

要使用这些,可以设置队列的代理(而不是设置请求的代理)为实现这些selector的控制器。

       ASINetworkQueues的使用和NSOperationQueues有一点不同,就是添加到ASINetworkQueues的请求并不会马上开始执行。当使用一个ASINetworkQueue时,添加你想运行的操作,然后调用[queue go]。当你开启一个队列并打开“进度控制”标志时,它首先会为队列中的每个请求发送一个获取头部信息的请求,以获得要下载的数据的大小。一旦队列获得了要下载的大小,它能准确的显示整个下载过程,真正的下载也会开始。

注意:

       当你添加一个请求到一个已经开始的ASINetworkQueue中会发生什么?当你使用ASINetworkQueue跟踪一些请求的整个进展,当添加一个新的请求到队列,只有新的请求开始运行的时候,整个队列会进入后台运行。当队列开始运行的时候后,新添加的请求不会再请求头部信息,所以当你一次添加很多请求到一个已经开始运行的队列,整个进度不会立刻更新。

如果一个队列已经开始运行,你不需要再调用[queuego]。

    当ASINetworkQueue中的一个请求执行失败时,队列默认会取消所有的请求。你可以通过 [queue setShouldCancelAllRequestsOnFailure:NO]

取消这个属性。

 ASINetworkQueue只能运行ASIHTTPRequest操作,它们不能用于一般的操作。添加一个非ASIHTTPRequest的NSOperation会触发一个异常。

     注意:这个一个完整的演示基本的创建和使用ASINetworkQueue例子:http://gist.github.com/150447。

1.7 取消一个异步请求

       调用[request cancel]取消一个异步请求(一个以[ [request startAsynchronous] ]开始的请求或者你创建的运行在队列中的请求)。注意你不能取消一个同步请求。

当你取消一个请求,这个请求会把这个当作一个错误,会调用请求的代理或者队列的代理的失败处理方法。如果你不希望这个行为,在取消一个请求之前设置这个请求的代理为nil或者使用方法clearDelegatesAndCancel取消请求。

           //Cancels an asynchronous request

           [requestcancel]

           //Cancels an asynchronous request, clearing all delegates and blocks first

            [requestclearDelegatesAndCancel];

使用一个ASINetworkQueue时,当你取消了队列中的一个请求,那么队列中所有的请求都会被取消除非你设置了队列的属性shouldCancelAllRequestsOnFailure为NO(YES是默认值)。

        // When a request inthis queue fails or is cancelled, other requests will continue to run

        [queuesetShouldCancelAllRequestsOnFailure:NO];

        // Cancel all requestsin a queue

        [queue cancelAllOperations];

1.8 当一个请求将要结束之前安全的处理即将被销毁的代理

请求不retain它们的代理,所以当请求正在执行的时候你的代理可能会被释放掉,清除请求的代理属性是至关重要的。在大多数情况下,如果你的代理将要被释放,你也不再关心这个请求的状态,所以你可能也想取消这个请求。

    在下面的例子中,我们的控制器有一个属性为retain的ASIHTTPRequest类型的实例变量。我们在方法delloc的实现中调用请求的clearDelegatesAndCancel方法,正好在在释放这个请求之前。

       // Ddealloc method for ourcontroller

       - (void)dealloc

       {

              [requestclearDelegatesAndCancel];

               [requestrelease];

               ...

              [superdealloc];

       }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值