1

1 時間あたり 125 回の API 呼び出し制限で 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

あなたのアプローチは、失敗し始めた後でも操作を継続します。

操作を 1 つずつ実行する必要があるが、失敗ブロックに到達したら停止する必要がある場合は、前の要求の完了ブロックに新しい要求をキューに入れます。

(このコードは、 iPhone の NSOperationQueue での AFNetworking Synchronous Operationへの回答からのものです。私は書いていません。)

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 に答える