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, 0) 

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

Quel est l’avantage d’utiliser dispatch_get_global_queue sur la queue principale?

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

La principale raison pour laquelle vous utilisez la queue par défaut sur la queue 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 queue 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 }); }); 

Toutes les files d’attente DISPATCH_QUEUE_PRIORITY_X sont des files d’attente simultanées (ce qui signifie qu’elles peuvent exécuter plusieurs tâches à la fois) et sont FIFO dans le sens où les tâches dans une queue donnée commenceront à s’exécuter en utilisant l’ordre “premier entré, premier sorti”. Ceci est en comparaison avec la queue principale (à partir de dispatch_get_main_queue ()), qui est une queue série (les tâches commenceront à s’exécuter et se termineront dans l’ordre dans lequel elles sont reçues).

Donc, si vous envoyez 1000 blocs dispatch_async () à DISPATCH_QUEUE_PRIORITY_DEFAULT, ces tâches commenceront à s’exécuter dans l’ordre dans lequel vous les avez envoyées dans la queue. De même pour les files d’attente HIGH, LOW et BACKGROUND. Tout ce que vous envoyez dans l’une de ces files d’attente est exécuté en arrière-plan sur des threads différents, loin de votre thread d’application principal. Par conséquent, ces files d’attente conviennent à l’exécution de tâches telles que le téléchargement en arrière-plan, la compression, le calcul, etc.

Notez que l’ordre d’exécution est FIFO par queue. Donc, si vous envoyez 1000 tâches dispatch_async () aux quatre files d’attente simultanées, en les divisant de manière égale et en les envoyant à BACKGROUND, LOW, DEFAULT et HIGH dans l’ordre (vous planifiez les 250 dernières tâches de la queue HIGH), Les premières tâches que vous verrez commencer seront sur cette queue HIGH, car le système a pris votre implication que ces tâches doivent parvenir à la CPU aussi rapidement que possible.

Notez aussi que je dis “commenceront à s’exécuter dans l’ordre”, mais gardez à l’esprit que les files d’attente concurrentes ne seront pas forcément exécutées dans l’ordre en fonction de la durée de chaque tâche.

Selon Apple:

https://developer.apple.com/library/content/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

Une queue de dissortingbution simultanée est utile lorsque vous avez plusieurs tâches pouvant être exécutées en parallèle. Une queue simultanée est toujours une queue dans la mesure où elle désactive les tâches dans un ordre premier entré, premier sorti; Cependant, une queue simultanée peut retirer des tâches supplémentaires avant la fin des tâches précédentes. Le nombre réel de tâches exécutées par une queue simultanée à un moment donné est variable et peut changer dynamicment lorsque les conditions de votre application changent. De nombreux facteurs affectent le nombre de tâches exécutées par les files d’attente simultanées, notamment le nombre de cœurs disponibles, la quantité de travail effectuée par d’autres processus et le nombre et la priorité des tâches dans les autres files d’attente de dissortingbution en série.

Fondamentalement, si vous envoyez ces 1000 blocs dispatch_async () à une queue DEFAULT, HIGH, LOW ou BACKGROUND, ils commenceront tous à s’exécuter dans l’ordre dans lequel vous les envoyez. Cependant, les tâches plus courtes peuvent se terminer avant les tâches plus longues. Les raisons à cela sont si des cœurs de processeur sont disponibles ou si les tâches de la queue en cours effectuent un travail non intensif sur le plan informatique (ce qui amène le système à penser qu’il peut envoyer des tâches supplémentaires en parallèle, quel que soit le nombre de cœurs).

Le niveau de concurrence est entièrement géré par le système et dépend de la charge du système et d’autres facteurs déterminés en interne. Telle est la beauté de Grand Central Dispatch (le système dispatch_async ()): il vous suffit de transformer vos unités de travail en blocs de code, de définir une priorité (en fonction de la file d’attente choisie) et de laisser le système gérer le rest.

Donc, pour répondre à votre question ci-dessus: vous avez partiellement raison. Vous “demandez à ce code” d’effectuer des tâches simultanées sur une queue simultanée globale au niveau de priorité spécifié. Le code dans le bloc s’exécutera en arrière-plan et tout code supplémentaire (similaire) s’exécutera potentiellement en parallèle en fonction de l’évaluation des ressources disponibles par le système.

La queue “principale” (de dispatch_get_main_queue ()) est une queue série (non concurrente). Les tâches envoyées à la queue principale seront toujours exécutées dans l’ordre et se termineront toujours dans l’ordre. Ces tâches seront également exécutées sur le thread d’interface utilisateur, ce qui convient à la mise à jour de votre interface utilisateur avec les messages de progression, les notifications d’achèvement, etc.

Version rapide

Ceci est la version Swift de la réponse Objective-C de David. Vous utilisez la queue globale pour exécuter des tâches en arrière-plan et la queue principale pour mettre à jour l’interface utilisateur.

Swift 3

 DispatchQueue.global(qos: .background).async { // Background Thread DispatchQueue.main.async { // Run UI Updates } }