1

我正在从 API 调用限制为每小时 125 次的 Web 服务中提取数据。我对用户数据的初始同步将使用类似于下面的方法。我无法理解下面代码的并发含义的正确性。

我将一系列 AFHTTPRequestOperation 添加到串行 NSOPerationsQueue (最大并发计数 = 1)。结果调用异步返回并导致方法处理数据字典。由于 API 调用限制,我知道在某些时候我的代码会失败并开始返回错误字典。

我是否可以期望以下代码按顺序返回完整的数据字典,或者由于回调的异步性质,它们中的一些可以在较早的请求之前完成吗?

因为我正在尝试进行初始同步,所以我想确保一旦代码由于 API 调用限制而失败,在失败点之前我的数据中没有“漏洞”。

-(void)addRequestWithString:(NSString*)requestString
{


    // 1: Create a NSURL and a NSURLRequest to points to the web service providing data. Add Oauth1 information to the request, including any extra parameters that are not in scope of Oauth1 protocol

    NSURL *url = [NSURL URLWithString:requestString];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [ self.auth authorizeRequest:request withExtraParams:self.extraAuthParameters];



    // 2: Use AFHTTPRequestOperation class, alloc and init it with the request.
    AFHTTPRequestOperation *datasource_download_operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    // 3: Give the user feedback, while downloading the data source by enabling network activity indicator.
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

    // 4: By using setCompletionBlockWithSuccess:failure:, you can add two blocks: one for the case where the operation finishes successfully, and one for the case where it fails.
    [datasource_download_operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {



        NSDictionary* dictonary = [NSJSONSerialization JSONObjectWithData:(NSData *)responseObject
                                                                  options:NSJSONReadingMutableContainers error:&error];


        [self processResponseDictionary:dictonary];

        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

    } failure:^(AFHTTPRequestOperation *operation, NSError *error){

        // 8: In case you are not successful, you display a message to notify the user.
        // Connection error message
        DLog(@"API fetch error: %@", error);

        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    }];

    // 9: Finally, add ìdatasource_download_operationî to ìdownloadQueueî of PendingOperations.
    [[self syncQueue] addOperation:datasource_download_operation];

}
4

1 回答 1

1

即使它们开始失败,您的方法仍将继续操作。

如果您需要一次执行一个操作,但在遇到失败块时停止,则将新请求排入先前请求的完成块中。

(此代码来自对AFNetworking Synchronous Operation in NSOperationQueue on iPhone的回答;不是我写的。)

NSEnumerator *enumerator = [operations reverseObjectEnumerator];
AFHTTPRequestOperation *currentOperation = nil;
AFHTTPRequestOperation *nextOperation = [enumerator nextObject]; 
while (nextOperation != nil && (currentOperation = [enumerator nextObject])) {
  currentOperation.completionBlock = ^{
    [client enqueueHTTPRequestOperation:nextOperation];
  }
  nextOperation = currentOperation;
}
[client enqueueHTTPRequestOperation:currentOperation];

如果命中失败块,则以下操作将永远不会入队。

于 2013-07-02T15:18:18.987 回答