objective-c asynchronous dispatch-async

objective c - Entendiendo dispatch_async



objective-c asynchronous (3)

Versión rápida

Esta es la versión Swift de la respuesta de David Objective-C. 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 } }

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 misma es que devuelve una cola simultánea global de un nivel de prioridad determinado?

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

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


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

Por ejemplo, si estoy descargando un archivo de Internet y deseo actualizar al usuario sobre el progreso de la descarga, ejecutaré la descarga en la cola de prioridad predeterminada y actualizaré la interfaz de usuario en la cola principal de forma asíncrona.

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 dada comenzarán a ejecutarse usando el orden de "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 recibieron).

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 las envió a la cola. Del mismo modo para las colas HIGH, LOW y BACKGROUND. Todo lo que envíe en 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 como la descarga en segundo plano, la compresión, el cálculo, etc.

Tenga en cuenta que el orden de ejecución es FIFO en una base por cola. Por lo tanto, si envía 1000 tareas dispatch_async () a las cuatro colas concurrentes diferentes, dividiéndolas uniformemente y enviándolas a BACKGROUND, LOW, DEFAULT y HIGH en orden (es decir, programa las últimas 250 tareas en la cola HIGH), es muy probable que Las primeras tareas que verá comenzando estarán en esa cola ALTA, ya que el sistema ha tomado su implicación de que esas tareas deben llegar a la CPU lo más rápido posible.

Tenga en cuenta también que digo que "comenzará a ejecutarse en orden", pero tenga en cuenta que, como colas simultáneas, las cosas no necesariamente terminarán de ejecutarse en orden, según el tiempo que transcurra para cada tarea.

Según Apple:

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

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

Básicamente, si envía esos 1000 bloques dispatch_async () a una cola POR DEFECTO, ALTA, BAJA o ANTECEDENTES, todos comenzarán a ejecutarse en el orden en que los envió. Sin embargo, las tareas más cortas pueden terminar antes que las más largas. Las razones detrás de esto son si hay núcleos de CPU disponibles o si las tareas de la cola actual están realizando un trabajo computacional no intensivo (lo que hace que el sistema piense que puede enviar tareas adicionales en paralelo, independientemente de la cantidad 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 ()): simplemente hace que sus unidades de trabajo sean bloques de código, establezca una prioridad para ellos (según la cola que elija) y deje que el sistema se encargue del resto.

Entonces, para responder a tu pregunta anterior: eres parcialmente correcto. Usted está "pidiendo a ese código" que realice 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" en la otra parte (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 terminarán en orden. Estas tareas también se ejecutarán en el subproceso de la interfaz de usuario, por lo que es adecuado para actualizar su interfaz de usuario con mensajes de progreso, notificaciones de finalización, etc.