39 votes

attendre que plusieurs opérations soient exécutées, y compris le bloc d'achèvement (AFNetworking)

j'ai de multiples opérations(afnetworking demandes) avec un délai d'exécution de bloc qui prend un certain temps à s'exécuter et un coredata objet qui doit être sauvé à la fin de toutes les demandes

MyCoreDataObject *coreDataObject;

AFHTTPRequestOperation *operation1 = [[AFHTTPRequestOperation alloc] initWithRequest:request1];
[operation1 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    coreDataObject.attribute1 = responseObject;
    sleep(5);
}];
[operation1 start];

AFHTTPRequestOperation *operation2 = [[AFHTTPRequestOperation alloc] initWithRequest:request1];
[operation2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    coreDataObject.attribute2 = responseObject;
    sleep(10);
}];
[operation1 operation2];

[context save:nil];

bien sûr, cela ne fonctionne pas comme voulu, car la demande est asynchrone. j'ai essayé d'ajouter un nsoperationqueue comme suit

NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
[operationQueue setMaxConcurrentOperationCount:2];

AFHTTPRequestOperation *operation1 = [[AFHTTPRequestOperation alloc] initWithRequest:request1];
[operation1 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    coreDataObject.attribute1 = responseObject;
    sleep(5);
}];
[operationQueue addOperation:operation1];

AFHTTPRequestOperation *operation2 = [[AFHTTPRequestOperation alloc] initWithRequest:request1];
[operation2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    coreDataObject.attribute2 = responseObject;
    sleep(10);
}];
[operationQueue addOperation:operation2];

[imageQueue waitUntilAllOperationsAreFinished];
[context save:nil];

cela ressemble un peu mieux. à l'aide de waitUntilAllOperationsAreFinished ma file d'attente bloque le thread courant jusqu'à ce que mes demandes sont finis, mais pas jusqu'à ce que mon successBlocks sont finis, ce qui est vraiment ce dont j'ai besoin.

toutes les idées sur la façon de réaliser cela dans une bonne voie?

merci à l'avance!

84voto

Ken Thomases Points 21131

Utilisez des groupes d'expédition.

 dispatch_group_t group = dispatch_group_create();

MyCoreDataObject *coreDataObject;

dispatch_group_enter(group);
AFHTTPRequestOperation *operation1 = [[AFHTTPRequestOperation alloc] initWithRequest:request1];
[operation1 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    coreDataObject.attribute1 = responseObject;
    sleep(5);
    dispatch_group_leave(group);
}];
[operation1 start];

dispatch_group_enter(group);
AFHTTPRequestOperation *operation2 = [[AFHTTPRequestOperation alloc] initWithRequest:request1];
[operation2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    coreDataObject.attribute2 = responseObject;
    sleep(10);
    dispatch_group_leave(group);
}];
[operation2 start];

dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_release(group);

[context save:nil];
 

15voto

wzs Points 883

AFNetworking a conçu une méthode pour ce type d'opérations, qui résume GCD:

-enqueueBatchOfHTTPRequestOperationsWithRequests:progressBlock:completionBlock:

-enqueueBatchOfHTTPRequestOperations:progressBlock:completionBlock:

Jetez un coup d'oeil à la FAQ

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X