iphone - ¿Cómo modificar la prioridad de una cola GCD personalizada?
ios concurrency (3)
Creo que te estás perdiendo el punto de las actividades asíncronas. Y el comentario de @RobertRyan acerca de que las actualizaciones de IU no se muestran rápidamente si se realizan en colas secundarias es incorrecto. Todas las actualizaciones de la interfaz de usuario deben realizarse en la cola principal. Período.
Pero volvamos a GCD y la cola asíncrona. @Sven tiene razón en que no puede cambiar la prioridad de las colas de envío. Las colas en GCD funcionan de manera FIFO (primero en entrar, primero en salir), por lo que el orden en que se ponen en cola es el orden en que se realizan. Esto es parte de por qué el uso de GCD es seguro para subprocesos; tiene la garantía de que no se encontrará con ningún problema debido a esta prioridad de cola FIFO. Lo segundo que hay que entender es que cuando despachas_asincroniza una cola, el sistema operativo no ofrece ninguna garantía de cuándo se procesará esa cola. Es un tipo de proceso que lo establece y lo olvida. Si necesita saber cuándo finaliza el procesamiento de la cola, debe configurar un controlador de bloque de finalización (notará que muchos de los Frameworks de Apple han comenzado a implementar esto) para recibir una notificación al respecto. Esta es la razón por la cual Apple sugiere anidar una llamada dispatch_async dentro de su primera llamada dispatch_async y solicitar el hilo principal para las actualizaciones de la interfaz de usuario. Entonces, tu código se vería así:
dispatch_async(q, ^{
[self performHeavyCalculations];
dispatch_async(dispatch_get_main_queue, ^{
// some UI updates
});
});
Debido a la forma en que el GCD se pone en cola y se sale de la cola, el envío de las actualizaciones de la interfaz de usuario de forma asíncrona a la cola principal permitirá que se realicen las actualizaciones de la interfaz de usuario sin que se produzca un retraso perceptible para el usuario. Si las actualizaciones de su interfaz de usuario dependen del resultado de los cálculos de Excelentes cálculos, deberá configurar un controlador de finalización o un esquema de delegación para notificar a la cola principal cuando esté completa, de modo que se puedan realizar las actualizaciones. Si el retraso entre los cálculos y la actualización es demasiado largo, es posible que deba analizar lo que está haciendo en el método de cálculo que está demorando tanto.
He creado una cola de GCD como esta:
dispatch_queue_t q = dispatch_queue_create("com.testcompany.myqueue", NULL);
Cuando envío tareas a esa cola, es mucho más lento que simplemente ejecutar la tarea en el hilo principal.
dispatch_async(q, ^(void) {
[self performHeavyCalculationAndUpdateUI];
});
Mi sospecha es que la cola tiene una prioridad muy baja por defecto. ¿Cómo puedo cambiar la prioridad de esta cola? ¿O hay algo más que debo hacer?
Las colas de envío no tienen una prioridad que puedas cambiar.
Puede cambiar la cola de destino de sus colas en serie utilizando las funciones dispatch_set_target_queue
y usar la cola global DISPATCH_QUEUE_PRIORITY_HIGH
. Esto solo garantiza que se programará antes que cualquier otro bloque en cola en las colas con la prioridad predeterminada o baja. Una vez que su bloque comience a ejecutarse, no se ejecutará más rápido ni más lento sin importar en qué cola se programó.
Su problema más probable es la actualización de su GUI, vea la respuesta de Robert Ryans.
Si está haciendo cosas de UIKit, en su bloque que se ejecuta en la cola secundaria, envíe las actualizaciones de la interfaz de usuario a la cola principal desde dentro de la cola secundaria a través de:
dispatch_async(q, ^(void) {
[self performHeavyCalculationAndUpdateUI];
dispatch_async(dispatch_get_main_queue(), ^{
// do my ui update
});
});
Simplemente envíe las pocas líneas que actualizan la interfaz de usuario a la cola principal y verá que no es una cuestión de prioridades de la cola, sino que simplemente se asegura de que las actualizaciones de la interfaz de usuario se realicen en la cola principal.