AFNetworking:重试操作时访问完成处理程序

给一些上下文:我试图实现一个全局error handling程序的身份validation错误(使用令牌身份validation,而不是基本),应该尝试重新validation,然后重复原始失败的请求(请参阅我以前的问题: AFNetworking:Handle全局错误并重复请求 )

目前的做法是为AFNetworkingOperationDidFinishNotification注册一个观察者,该观察者进行重新authentication,并且(如果authentication成功)重复原始请求:

 - (void)operationDidFinish:(NSNotification *)notification { AFHTTPRequestOperation *operation = (AFHTTPRequestOperation *)[notification object]; if(![operation isKindOfClass:[AFHTTPRequestOperation class]]) { return; } if(403 == [operation.response statusCode]) { // try to re-authenticate and repeat the original request [[UserManager sharedUserManager] authenticateWithCredentials... success:^{ // repeat original request // AFHTTPRequestOperation *newOperation = [operation copy]; // copies too much stuff, eg. response (although the docs suggest otherwise) AFHTTPRequestOperation *newOperation = [[AFHTTPRequestOperation alloc] initWithRequest:operation.request]; // PROBLEM 1: newOperation has no completion blocks. How to use the original success/failure blocks here? [self enqueueHTTPRequestOperation:newOperation]; } failure:^(NSError *error) { // PROBLEM 2: How to invoke failure block of original operation? } ]; } } 

但是,我偶然发现了有关请求操作的完成块的一些问题:

  • 当重复原始请求时,我显然希望它的完成块被执行。 但是, AFHTTPRequestOperation不保留对传入的成功和失败块的引用(请参阅setCompletionBlockWithSuccess:failure: NSOperation并复制NSOperationcompletionBlock可能不是一个好主意,因为AFURLConnectionOperation的文档指出:

    操作副本不包含completionBlockcompletionBlock通常会强烈地捕获对self的引用,这也许令人惊讶的是,在复制时会指向原始操作。

  • 如果重新authentication失败,我想调用原始请求的失败块。 所以,我再次需要直接访问这个。

我在这里错过了什么? 任何想法的替代方法? 我应该提交function请求吗?

我在Art.sy的投资组合应用程序中提出了这个问题。 我最终得出的结论是创build一个NSOperationQueue子类,它具有在失败后创build各种AFNetworking HTTP操作的副本的function(在放弃之前,每个URL最多可以完成三次)。

你尝试了以下吗?

 // set success / failure block of original operation [newOperation setCompletionBlock:[operation.completionBlock copy]]; [operation setCompletionBlock:nil]; 

请注意,如果您在原始完成/失败块(即访问任何ivars)中捕获自己,则在执行newOperation的完成块时实际访问原始操作实例。 但是这是你想要的,对吧?

通知处理程序在操作的完成块之前执行。 所以你应该将原始操作的完成块设置为零,以防止它执行两次。

注意完成块在执行后被设置为零(见AFURLConnectionOperation)。

在authenticateWithCredentials失败块,你不应该做任何事情。 原来的操作已经完成,并且已经执行了它的故障块。