242 votes

Comprendre dispatch_async

J'ai une question autour de ce code

 dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSData* data = [NSData dataWithContentsOfURL: 
      kLatestKivaLoansURL];
    [self performSelectorOnMainThread:@selector(fetchedData:) 
      withObject:data waitUntilDone:YES];
});
 

Le premier paramètre de ce code est

 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT) 
 

Demandons-nous à ce code d'effectuer des tâches en série sur la file d'attente globale dont la définition elle-même indique qu'elle renvoie une file d'attente simultanée globale d'un niveau de priorité donné?

Quel est l'avantage d'utiliser dispatch_get_global_queue sur la file d'attente principale?

Je suis confus. Pourriez-vous s'il vous plaît m'aider à mieux comprendre cela?

532voto

David Points 6605

La principale raison pour laquelle vous utilisez la file d'attente par défaut sur la file d'attente principale est d'exécuter des tâches en arrière-plan.

Par exemple, si je télécharge un fichier depuis Internet et que je souhaite mettre l'utilisateur à jour sur l'avancement du téléchargement, je lancerai le téléchargement dans la file d'attente par défaut prioritaire et mettrai à jour l'interface utilisateur de manière asynchrone.

 dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
    //Background Thread
    dispatch_async(dispatch_get_main_queue(), ^(void){
        //Run UI Updates
    });
});
 

200voto

user2547242 Points 631

Tous les DISPATCH_QUEUE_PRIORITY_X les files d'attente sont concurrentes, les files d'attente (ce qui signifie qu'ils peuvent exécuter plusieurs tâches à la fois), et sont FIFO dans le sens que les tâches au sein d'une file d'attente commencera à exécuter à l'aide du "premier entré, premier sorti" pour. C'est en comparaison à la file d'attente principale (à partir de dispatch_get_main_queue()), qui est une série de file d'attente (tâches commencera à exécuter et terminer l'exécution dans l'ordre dans lequel ils sont reçus).

Donc, si vous envoyez 1000 dispatch_async() bloque à DISPATCH_QUEUE_PRIORITY_DEFAULT, ces tâches permettra de commencer à exécuter dans l'ordre qui vous a envoyés dans la file d'attente. De même pour le HAUT, BAS, arrière-plan, les files d'attente. Tout ce que vous envoyez dans l'une de ces files d'attente est exécutée en arrière-plan sur d'autres threads, loin de votre thread principal de l'application. Par conséquent, ces files d'attente sont appropriés pour l'exécution de tâches telles que le téléchargement de fond, de compression, de calcul, etc.

Notez que l'ordre d'exécution est FIFO par la file d'attente. Donc, si vous envoyez 1000 dispatch_async() les tâches à quatre différentes simultanées files d'attente, uniformément de les diviser et de les envoyer à l'arrière-plan, les FAIBLES, DÉFAUT et ÉLEVÉ dans l'ordre (c'est à dire vous calendrier les 250 dernières tâches sur le HAUT de la file d'attente), il est très probable que les tâches que vous voyez de départ vont être sur ce HAUT de la file d'attente que le système a pris votre implication que ces tâches doivent se rendre sur le CPU le plus rapidement possible.

Notez également que je dis "commencera à exécuter dans l'ordre", mais gardez à l'esprit qu'en tant que concurrente des files d'attente, les choses ne sont pas nécessairement TERMINER l'exécution de commande en fonction de la longueur de temps pour chaque tâche.

Comme par Apple:

http://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

Un concurrent à l'envoi de la file d'attente est utile lorsque vous avez plusieurs tâches peuvent s'exécuter en parallèle. Une concurrente de la file d'attente est toujours une file d'attente en ce qu'il retire les tâches dans un de premier, premier ordre"; cependant, le concurrent d'attente file d'attente des tâches supplémentaires avant toutes les tâches précédentes terminer. Le nombre de tâches exécutées par un concurrent à la file d'attente à un moment donné est variable et peut changer dynamiquement selon les conditions de votre demande de changement. De nombreux facteurs influent sur le nombre de tâches exécutées par la concurrente de files d'attente, y compris le nombre de cœurs disponibles, le montant des travaux effectués par d'autres processus, et le nombre et la priorité des tâches dans d'autres envoi en série des files d'attente.

En gros, si vous envoyez ces 1000 dispatch_async() bloque par DÉFAUT, en HAUT, en BAS, ou l'arrière-plan de la file d'attente, ils seront tous de commencer à exécuter dans l'ordre que vous leur envoyez. Cependant, la plus courte des tâches peut se terminer avant plus. Raisons derrière cela si il y a des cœurs processeurs disponibles ou si la file d'attente de tâches sont à effectuer de calculs non-travail intensif (rendant ainsi le système pense qu'il peut envoyer d'autres tâches en parallèle, indépendamment du nombre de cœurs).

Le niveau de la concurrence est entièrement assurée par le système et est basé sur le système de charge et d'autres à l'interne déterminé facteurs. C'est la beauté de Grand Central Dispatch (le dispatch_async (système de) - vous venez de faire votre travail comme unités de blocs de code, définir une priorité pour eux (basé sur la file d'attente que vous choisissez) et laisser le système gérer le reste.

Donc, pour répondre à votre question ci-dessus: vous êtes partiellement correcte. Vous êtes "en demandant que le code" pour effectuer des tâches simultanées mondiale simultanée de la file d'attente au niveau de priorité donné. Le code dans le bloc exécutera en arrière-plan et tous les autres semblables) code s'exécute potentiellement en parallèle selon le système d'évaluation des ressources disponibles.

Le "principal" de la file d'attente sur l'autre main (à partir de dispatch_get_main_queue()) est une série de file d'attente (pas en même temps). Les tâches envoyées à la file d'attente principale sera toujours exécuté dans l'ordre et sera toujours finir dans l'ordre. Ces tâches seront également exécutés sur le Thread de l'INTERFACE utilisateur de sorte qu'il est adapté pour la mise à jour de l'INTERFACE utilisateur avec les progrès des messages, notifications de clôture, etc.

Espérons que cela aide.

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