2012-05-03 9 views
21

Estoy tratando estos dos enfoques:Ejecutar en Next Run Loop: ¿Qué hay de malo con GCD?

dispatch_async(dispatch_get_main_queue(),^{ 
    [self handleClickAsync]; 
}); 

y

[self performSelector:@selector(handleClickAsync) withObject:nil afterDelay:0]; 

en respuesta a una pulsación de botón.

El segundo permite resaltar UIButton como se esperaría y realizar el handleClickAsync en el siguiente ciclo de ejecución (supongo que "algún día después" seguro). El primero no permite que la instancia UIButton se encienda hasta que la operación esté completamente completa.

¿Cuál es la forma correcta de hacer esto con GCD, o es performSelector siendo la única manera?

+0

Es de suponer que está llamando esto desde dentro de otra cola de distribución? Si es así, ejecutará todos los comandos secuencialmente dentro de la cola. ¿Es posible que llame a este método antes de comenzar la operación? –

+0

No estoy seguro. Llamo esto directamente desde un 'touchesEnded', que viene gratis en la subclase' UIView' (o UIButton en este caso). –

+0

No estoy seguro de por qué está haciendo una asociación entre dispatch_async y la ejecución del runloop ... –

Respuesta

36

Creo que la respuesta se encuentra aquí en una discussion of the main dispatch queue:

Esta cola trabaja con bucle de ejecución de la aplicación (si la hay) para intercalar la ejecución de tareas en cola con la ejecución de otras fuentes de eventos adjunto al ciclo de ejecución.

En otras palabras, la cola principal despacho establece una cola secundaria (junto con la cola de eventos estándar proporcionado por UIApplicationMain() para la manipulación de bloques presentados a la cola principal. Cuando los bloques están presentes en la cola, el bucle de ejecución se tareas desencola suplentes de la cola de eventos principal y la cola de envío por otro lado, la reference para el parámetro delay de -performSelector:withObject:afterDelay: notas que:.

Especificación de un retardo de 0 no necesariamente causan el selector a realizarse inmediatamente . El selector todavía está en cola en el hilo ' s ejecutar bucle y se realizó tan pronto como sea posible.

Por lo tanto, cuando se utiliza realizar selector, la operación se pone en cola al final de la cola de eventos principal, y no se realiza hasta después de todo delante de él en la cola (presumiblemente incluyendo el código para eliminar el realce de la UIButton) ha sido procesado. Sin embargo, cuando utiliza la cola de despacho principal, agrega el bloque a la cola secundaria, que probablemente se procesa inmediatamente (es decir, en el siguiente ciclo de ejecución), suponiendo que no haya otros bloques en la cola principal. En este caso, el código para deshabilitar el botón aún se encuentra en la cola del evento principal, mientras que el ciclo de ejecución procesa el evento desde la cola del bloque secundario.

+0

Esto tiene sentido, Sean, y parece explicar la realidad empírica. Voy a esperar unos días para marcar esto, acepto ver qué tipo de respuestas vienen. –

+0

Hmmm ... espero que alguien como @bbum venga y verifique esto, pero así no es como funciona SO, así que marcaré esto como la mejor respuesta provisionalmente (para siempre). Gracias de nuevo. –

22

creo que esto llegará a su punto:

[[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
    //bla bla bla 
}]; 
+0

Lo hizo por mí. :) –

+0

Sí. Esto esta funcionando! – Klaas

Cuestiones relacionadas