web-dev-qa-db-fra.com

Les blocs de réussite / échec d'AFNetworking sont-ils appelés sur le thread principal?

AFNetworking appelle-t-il le bloc d'achèvement sur le thread principal? ou est-il appelé en arrière-plan, m'obligeant à envoyer manuellement mes mises à jour de l'interface utilisateur au thread principal?

En utilisant du code au lieu de mots, voici l'exemple de code de la documentation AFNetworking avec l'appel à NSLog remplacé par une mise à jour de l'interface utilisateur:

AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
    self.label.text = JSON[@"text"];
} failure:nil];

Doit-il être écrit comme ceci à la place?

AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
    dispatch_async(dispatch_get_main_queue(), ^{
        self.label.text = JSON[@"text"];
    });
} failure:nil];
47
thomasd

Dans AFNetworking 2, AFHTTPRequestOperationManager a une propriété completionQueue.

La file d'attente de répartition pour le completionBlock des opérations de demande. Si NULL (par défaut), la file d'attente principale est utilisée.

    #if OS_OBJECT_USE_OBJC
    @property (nonatomic, strong, nullable) dispatch_queue_t completionQueue;
    #else
    @property (nonatomic, assign, nullable) dispatch_queue_t completionQueue;
    #endif

Dans AFNetworking 3, la propriété completionQueue a été déplacée vers AFURLSessionManager (que AFHTTPSessionManager étend).

La file d'attente de répartition pour completionBlock. Si NULL (par défaut), la file d'attente principale est utilisée.

@property (nonatomic, strong) dispatch_queue_t completionQueue;
@property (nonatomic, strong, nullable) dispatch_queue_t completionQueue;
31
onmyway133

Ils sont invoqués dans la file d'attente principale, sauf si vous définissez explicitement la file d'attente sur AFHTTPRequestOperation, comme indiqué dans setCompletionBlockWithSuccess:failure de AFHTTPRequestOperation.m

self.completionBlock = ^{
    if (self.error) {
        if (failure) {
            dispatch_async(self.failureCallbackQueue ?: dispatch_get_main_queue(), ^{
                failure(self, self.error);
            });
        }
    } else {
        if (success) {
            dispatch_async(self.successCallbackQueue ?: dispatch_get_main_queue(), ^{
                success(self, self.responseData);
            });
        }
    }
};
42
Marcelo Fabri

Comme tout le monde l'a expliqué, c'est dans le code source de l'AFNetworking, quant à la façon de le faire,

AFNetworking 2.xx:

// Create dispatch_queue_t with your name and DISPATCH_QUEUE_SERIAL as for the flag
dispatch_queue_t myQueue = dispatch_queue_create("com.CompanyName.AppName.methodTest", DISPATCH_QUEUE_SERIAL);

// init AFHTTPRequestOperation of AFNetworking
operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

// Set the FMDB property to run off the main thread
[operation setCompletionQueue:myQueue];

AFNetworking 3.xx :

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] init];
[self setCompletionQueue:myQueue];
5
OhadM

Vous pouvez définir la file d'attente de rappel d'achèvement en spécifiant d'achèvementGroupe, d'achèvementQueue voir le document d'API AFNetworking

1
Elaine