Entendiendo dispatch_async

Tengo preguntas sobre este código

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

El primer parámetro de este código es

 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 

¿Le estamos pidiendo a este código que realice tareas en serie en la cola global, cuya definición en sí misma es que devuelve la cola simultánea global de un nivel de prioridad dado?

¿Cuál es la ventaja de usar dispatch_get_global_queue en la cola principal?

Estoy confundido. ¿Podrías por favor ayudarme a entender esto mejor?

La razón principal por la que utiliza la cola predeterminada en la cola principal es ejecutar tareas en segundo plano.

Por ejemplo, si estoy descargando un archivo de Internet y quiero actualizar al usuario sobre el progreso de la descarga, ejecutaré la descarga en la cola predeterminada de prioridad y actualizaré la interfaz de usuario en la cola principal de forma asincrónica.

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

Todas las colas DISPATCH_QUEUE_PRIORITY_X son colas concurrentes (lo que significa que pueden ejecutar múltiples tareas a la vez) y son FIFO en el sentido de que las tareas dentro de una cola determinada comenzarán a ejecutarse utilizando el orden “primero en entrar, primero en salir”. Esto es en comparación con la cola principal (de dispatch_get_main_queue ()), que es una cola en serie (las tareas comenzarán a ejecutarse y terminarán de ejecutarse en el orden en que se reciben).

Por lo tanto, si envía 1000 bloques dispatch_async () a DISPATCH_QUEUE_PRIORITY_DEFAULT, esas tareas comenzarán a ejecutarse en el orden en que los envió a la cola. Del mismo modo para las colas HIGH, LOW y BACKGROUND. Todo lo que envíe a cualquiera de estas colas se ejecuta en segundo plano en subprocesos alternativos, lejos del subproceso principal de la aplicación. Por lo tanto, estas colas son adecuadas para ejecutar tareas tales como descargas en segundo plano, compresión, cálculo, etc.

Tenga en cuenta que el orden de ejecución es FIFO por cola. Por lo tanto, si envía 1000 tareas dispatch_async () a las cuatro colas concurrentes diferentes, las divide en partes iguales y las envía a ANTECEDENTES, BAJO, POR DEFECTO y ALTO en orden (es decir, progtwig las últimas 250 tareas en la cola ALTA), es muy probable que las primeras tareas que veas comenzar estarán en esa cola HIGH ya que el sistema ha tomado en cuenta que esas tareas necesitan llegar a la CPU lo más rápido posible.

Tenga en cuenta también que digo “comenzará a ejecutarse en orden”, pero tenga en cuenta que, como colas concurrentes, las cosas no necesariamente se ejecutarán en orden en función del período de tiempo para cada tarea.

Según Apple:

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

Una cola de despacho concurrente es útil cuando tiene múltiples tareas que pueden ejecutarse en paralelo. Una cola simultánea sigue siendo una cola en que dequeues tareas en orden de primero en entrar, primero en salir; sin embargo, una cola simultánea puede dequeue tareas adicionales antes de que finalice cualquier tarea anterior. El número real de tareas ejecutadas por una cola concurrente en cualquier momento dado es variable y puede cambiar dinámicamente a medida que cambian las condiciones de la aplicación. Muchos factores afectan la cantidad de tareas ejecutadas por las colas simultáneas, incluida la cantidad de núcleos disponibles, la cantidad de trabajo que realizan otros procesos y el número y la prioridad de las tareas en otras colas de envío en serie.

Básicamente, si envía esos 1000 bloques dispatch_async () a una cola DEFAULT, HIGH, LOW o BACKGROUND, todos comenzarán a ejecutarse en el orden en que los envíe. Sin embargo, las tareas más cortas pueden terminar antes de las más largas. Las razones detrás de esto son si hay núcleos de CPU disponibles o si las tareas de cola actuales realizan un trabajo computacionalmente no intensivo (lo que hace que el sistema piense que puede despachar tareas adicionales en paralelo independientemente del recuento de núcleos).

El nivel de concurrencia es manejado completamente por el sistema y se basa en la carga del sistema y otros factores determinados internamente. Esta es la belleza de Grand Central Dispatch (el sistema dispatch_async ()): usted simplemente crea sus unidades de trabajo como bloques de código, establece una prioridad para ellos (según la cola que elija) y deja que el sistema maneje el rest.

Entonces para responder a su pregunta anterior: usted está parcialmente correcto. Está “pidiendo ese código” para realizar tareas simultáneas en una cola simultánea global en el nivel de prioridad especificado. El código en el bloque se ejecutará en segundo plano y cualquier código adicional (similar) se ejecutará potencialmente en paralelo dependiendo de la evaluación del sistema de los recursos disponibles.

La cola “principal” por otro lado (de dispatch_get_main_queue ()) es una cola en serie (no concurrente). Las tareas enviadas a la cola principal siempre se ejecutarán en orden y siempre finalizarán en orden. Estas tareas también se ejecutarán en el subproceso UI, por lo que es adecuado para actualizar su interfaz de usuario con mensajes de progreso, notificaciones de finalización, etc.

Versión Swift

Esta es la versión Swift de la respuesta Objective-C de David. Utiliza la cola global para ejecutar cosas en segundo plano y la cola principal para actualizar la interfaz de usuario.

Swift 3

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