Tengo una devolución de llamada que podría provenir de cualquier hilo. Cuando recibo esta devolución de llamada, me gustaría realizar una determinada tarea en el hilo principal.
¿Debo verificar si ya estoy en el hilo principal, o hay alguna penalización por no realizar esta verificación antes de llamar al código a continuación?
dispatch_async(dispatch_get_main_queue(), ^{
// do work here
});
Respuestas:
No, no necesita verificar si ya está en el hilo principal. Al enviar el bloque a la cola principal, solo está programando que el bloque se ejecute en serie en el hilo principal, lo que sucede cuando se ejecuta el ciclo de ejecución correspondiente.
Si ya está en el hilo principal, el comportamiento es el mismo: el bloque está programado y se ejecuta cuando se ejecuta el bucle de ejecución del hilo principal.
fuente
async
regresa a la cola principal, se ejecutará, pero eso puede estropear el tiempo esperado de sus acciones . Por ejemplo, el código de la IUviewDidLoad()
no se ejecuta hasta después de que se muestra la vista por primera vez .Para el caso de despacho asíncrono que describió anteriormente, no debería necesitar verificar si está en el hilo principal. Como indica Bavarious, esto simplemente se pondrá en cola para ejecutarse en el hilo principal.
Sin embargo, si intenta hacer lo anterior usando
dispatch_sync()
ay su devolución de llamada está en el hilo principal, su aplicación se bloqueará en ese punto. Describo esto en mi respuesta aquí , porque este comportamiento me sorprendió al mover algo de código-performSelectorOnMainThread:
. Como mencioné allí, creé una función auxiliar:que ejecutará un bloque sincrónicamente en el hilo principal si el método en el que se encuentra no está actualmente en el hilo principal, y simplemente ejecuta el bloque en línea si lo es. Puede utilizar una sintaxis como la siguiente para usar esto:
fuente
dispatch_set_specific()
ayudaría en el caso que describa: stackoverflow.com/a/12806754/19679 .Como se menciona en las otras respuestas, dispatch_async desde el hilo principal está bien.
Sin embargo, dependiendo de su caso de uso, hay un efecto secundario que puede considerar una desventaja: dado que el bloque está programado en una cola, no se ejecutará hasta que el control regrese al ciclo de ejecución, lo que tendrá el efecto de retrasarse La ejecución de tu bloque.
Por ejemplo,
Imprimirá:
Por esta razón, si esperaba que el bloque se ejecute entre los NSLog externos, dispatch_async no lo ayudaría.
fuente
No, no necesita verificar si está en el hilo principal. Así es como puedes hacer esto en Swift:
Está incluido como una función estándar en mi repositorio, échale un vistazo: https://github.com/goktugyil/EZSwiftExtensions
fuente