serial grand gcd example dispatchqueue create central ios concurrency grand-central-dispatch dispatch-async

ios - grand - swift 4 dispatch main



iPhone-Tema principal de Grand Central Dispatch (6)

Async significa asíncrono y deberías usarlo la mayor parte del tiempo. Nunca debe llamar a la sincronización en el hilo principal porque bloqueará su UI hasta que se complete la tarea. Usted aquí es una mejor manera de hacer esto en Swift:

runThisInMainThread { () -> Void in // Run your code like this: self.doStuff() } func runThisInMainThread(block: dispatch_block_t) { dispatch_async(dispatch_get_main_queue(), block) }

Está incluido como una función estándar en mi repositorio, échale un vistazo: https://github.com/goktugyil/EZSwiftExtensions

He estado utilizando con éxito el gran despacho central en mis aplicaciones, pero me preguntaba cuál es la verdadera ventaja de usar algo como esto:

dispatch_async(dispatch_get_main_queue(), ^{ ... do stuff

o incluso

dispatch_sync(dispatch_get_main_queue(), ^{ ... do stuff

Quiero decir, en ambos casos estás disparando un bloque para que se ejecute en el hilo principal, exactamente donde se ejecuta la aplicación y esto no ayudará a reducir la carga. En el primer caso, no tienes ningún control cuando se ejecutará el bloque. He visto casos de bloques que se ejecutan medio segundo después de dispararlos. El segundo caso, es similar a

[self doStuff];

¿derecho?

Me pregunto qué piensan ustedes.


El envío de bloques a la cola principal desde el hilo principal puede ser útil. Le da a la cola principal la posibilidad de manejar otros bloques que se han puesto en cola para que no solo bloquee la ejecución de todo lo demás.

Por ejemplo, podría escribir un servidor con un único hilo que, sin embargo, maneja muchas conexiones simultáneas. Siempre que ningún bloque individual en la cola lleve demasiado tiempo, el servidor se mantiene receptivo a las nuevas solicitudes.

Si su programa no hace más que pasar toda su vida respondiendo a los eventos, entonces esto puede ser bastante natural. Simplemente configura los controladores de eventos para que se ejecuten en la cola principal y luego llames a dispatch_main (), y es posible que no tengas que preocuparte por la seguridad de los hilos.


El envío de un bloque a la cola principal normalmente se realiza desde una cola de fondo para indicar que ha finalizado algún procesamiento de fondo, por ejemplo

- (void)doCalculation { //you can use any string instead "com.mycompany.myqueue" dispatch_queue_t backgroundQueue = dispatch_queue_create("com.mycompany.myqueue", 0); dispatch_async(backgroundQueue, ^{ int result = <some really long calculation that takes seconds to complete>; dispatch_async(dispatch_get_main_queue(), ^{ [self updateMyUIWithResult:result]; }); }); }

En este caso, estamos haciendo un cálculo extenso en una cola en segundo plano y necesitamos actualizar nuestra UI cuando el cálculo esté completo. Por lo general, la actualización de la IU debe hacerse desde la cola principal, por lo que ''señalizamos'' de nuevo a la cola principal utilizando un segundo dispatch_async anidado.

Probablemente existan otros ejemplos en los que desee enviar de vuelta a la cola principal, pero generalmente se hace de esta manera, es decir, anidado desde dentro de un bloque enviado a una cola de fondo.

  • procesamiento de fondo finalizado -> actualizar la interfaz de usuario
  • fragmento de datos procesados ​​en cola de fondo -> cola principal de señal para comenzar el siguiente fragmento
  • datos de la red entrante en la cola de fondo -> cola principal de la señal que ha llegado el mensaje
  • etcétera etcétera

En cuanto a por qué es posible que desee enviar a la cola principal de la cola principal ... Bueno, en general, aunque no concebiblemente, podría hacerlo para programar algún trabajo para hacer la próxima vez en el ciclo de ejecución.


Espero que entienda tu pregunta correctamente porque te preguntas acerca de las diferencias entre dispatch_async y dispatch_sync.

dispatch_async

enviará el bloque a una cola de forma asíncrona. Lo que significa que enviará el bloque a la cola y no esperará a que vuelva antes de continuar con la ejecución del código restante en su método.

dispatch_sync

enviará el bloque a una cola sincrónicamente. Esto evitará más ejecución del código restante en el método hasta que el bloque haya terminado de ejecutarse.

En su mayoría he usado un dispatch_async en una cola de segundo plano para obtener trabajo fuera de la cola principal y aprovechar cualquier núcleo adicional que pueda tener el dispositivo. Luego dispatch_async al hilo principal si necesito actualizar la interfaz de usuario.

Buena suerte


Un lugar donde es útil es para actividades de UI, como configurar un spinner antes de una operación prolongada:

- (void) handleDoSomethingButton{ [mySpinner startAnimating]; (do something lengthy) [mySpinner stopAnimating]; }

no funcionará, porque está bloqueando el hilo principal durante todo el proceso y no permite que UIKit realmente inicie el spinner.

- (void) handleDoSomethingButton{ [mySpinner startAnimating]; dispatch_async (dispatch_get_main_queue(), ^{ (do something lengthy) [mySpinner stopAnimating]; }); }

devolverá el control al bucle de ejecución, que programará la actualización de la IU, iniciará la ruleta y luego sacará lo siguiente de la cola de despacho, que es su procesamiento real. Cuando finaliza su procesamiento, se invoca la parada de animación y regresa al ciclo de ejecución, donde la interfaz de usuario se actualiza con la parada.


Swift 3 y 4

Ejecutando el código en el hilo principal

DispatchQueue.main.async { // Your code here }