iPhone-Hilo principal de Grand Central Dispatch


He estado usando con éxito, grand central dispatch 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 se está disparando un bloque para ser ejecutado en el hilo principal, exactamente donde se ejecuta la aplicación y esto no ayudará a reducir la carga. En el primer caso, no tiene ningún control sobre cuándo se ejecutará el bloque. He visto casos de bloques ejecutados medio segundo después de que los dispararas. El segundo caso, es similar a

[self doStuff];

¿Correcto?

Me pregunto qué piensan ustedes.

Author: Honey, 2011-10-26

6 answers

El envío de un bloque a la cola principal generalmente se realiza desde una cola en segundo plano para indicar que se ha terminado algún procesamiento en segundo plano, 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 largo cálculo en una cola en segundo plano y necesitamos actualizar nuestra interfaz de usuario cuando se complete el cálculo. La actualización de la interfaz de usuario normalmente tiene que hacerse desde la cola principal para que 'señalemos' de vuelta a la cola principal usando un segundo dispatch_async anidado.

Probablemente hay otros ejemplos en los que podrías querer enviar de nuevo 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 en segundo plano terminado - > actualizar interfaz de usuario
  • fragmento de datos procesados en la cola en segundo plano -> señal de la cola principal para iniciar el siguiente fragmento
  • datos de red entrantes en la cola en segundo plano - > señal de la cola principal que el mensaje ha llegado
  • etc etc

En cuanto a por qué es posible que desee enviar a la cola principal desde la cola principal... Bueno, generalmente no lo haría aunque posiblemente podría hacerlo para programar algún trabajo para hacer la próxima vez alrededor del bucle de carrera.

 291
Author: Robin Summerhill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-21 12:39:40

Enviar bloques a la cola principal desde el hilo principal puede ser útil. Le da a la cola principal la oportunidad de manejar otros bloques que se han puesto en cola para que no esté simplemente bloqueando todo lo demás de la ejecución.

Por ejemplo, podría escribir un servidor de subprocesos esencialmente único que, sin embargo, maneja muchas conexiones simultáneas. Mientras ningún bloque individual en la cola tome demasiado tiempo, el servidor permanece receptivo a las nuevas solicitudes.

Si su programa no hace más que pasar toda su vida respondiendo a los acontecimientos, entonces esto puede ser bastante natural. Solo tienes que configurar tus controladores de eventos para que se ejecuten en la cola principal y luego llamar a dispatch_main(), y es posible que no tengas que preocuparte por la seguridad del hilo en absoluto.

 15
Author: bames53,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-28 21:31:15

Espero que esté entendiendo su pregunta correctamente, ya que se está preguntando sobre 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 regrese 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.

He usado principalmente una dispatch_async a una cola en segundo plano para sacar trabajo 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

 11
Author: timthetoolman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-18 15:20:06

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

- (void) handleDoSomethingButton{

    [mySpinner startAnimating];

    (do something lengthy)
    [mySpinner stopAnimating];
}

No funcionará, porque está bloqueando el hilo principal durante su larga cosa y no dejar 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 interfaz de usuario, iniciando el spinner, y luego sacará lo siguiente de la cola de despacho, que es su procesamiento real. Cuando su procesamiento se realiza, el se llama a la parada de animación y se vuelve al bucle de ejecución, donde la interfaz de usuario se actualiza con la parada.

 7
Author: weaselfloss1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-13 23:53:13

Swift 3 & 4

Código en ejecución en el hilo principal

DispatchQueue.main.async {
    // Your code here
}
 3
Author: Niall Kiddle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-16 12:23:56

Async significa asíncrono y deberías usarlo la mayor parte del tiempo. Nunca debe llamar a sync en el hilo principal porque bloqueará su interfaz de usuario hasta que se complete la tarea. Aquí hay 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)
}

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

 1
Author: Esqarrouth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-06 03:44:53