tab guidelines bar ios macos objective-c-blocks grand-central-dispatch

guidelines - tab bar ios



¿Cómo puedo verificar que estoy ejecutándose en una cola de GCD determinada sin usar dispatch_get_current_queue()? (2)

Asigna el identificador que quieras utilizando dispatch_queue_set_specific() . Luego puede verificar su identificador usando dispatch_get_specific() .

Recuerde que dispatch_get_specific() es agradable porque comenzará en la cola actual y luego subirá por las colas de destino si la clave no está configurada en la actual. Esto generalmente no importa, pero puede ser útil en algunos casos.

Recientemente, tuve la necesidad de una función que pudiera usar para garantizar la ejecución sincrónica de un bloque determinado en una determinada cola de despacho en serie. Existía la posibilidad de que esta función compartida pudiera ser invocada por algo que ya se ejecutaba en esa cola, por lo que necesitaba verificar este caso para evitar un interbloqueo desde un envío síncrono a la misma cola.

Usé código como el siguiente para hacer esto:

void runSynchronouslyOnVideoProcessingQueue(void (^block)(void)) { dispatch_queue_t videoProcessingQueue = [GPUImageOpenGLESContext sharedOpenGLESQueue]; if (dispatch_get_current_queue() == videoProcessingQueue) { block(); } else { dispatch_sync(videoProcessingQueue, block); } }

Esta función se basa en el uso de dispatch_get_current_queue() para determinar la identidad de la cola en la que se está ejecutando esta función y la compara con la cola de destino. Si hay una coincidencia, sabe simplemente ejecutar el bloque en línea sin el envío a esa cola, porque la función ya se está ejecutando en él.

He escuchado cosas contradictorias sobre si era apropiado usar dispatch_get_current_queue() para hacer comparaciones como esta, y veo esta frase en los encabezados:

Recomendado solo para fines de depuración y registro:

El código no debe hacer suposiciones sobre la cola devuelta, a menos que sea una de las colas globales o una cola que el código haya creado. El código no debe suponer que la ejecución síncrona en una cola está a salvo del interbloqueo si esa cola no es la devuelta por dispatch_get_current_queue ().

Además, en iOS 6.0 (pero aún no para Mountain Lion), los encabezados de GCD ahora marcan esta función como obsoleta.

Parece que no debería usar esta función de esta manera, pero no estoy seguro de qué usar en su lugar. Para una función como la anterior que se dirigió a la cola principal, podría usar [NSThread isMainThread] , pero ¿cómo puedo verificar si estoy ejecutando en una de mis colas serie personalizadas para poder evitar un punto muerto?


Esta es una solución muy simple. No es tan eficiente como usar dispatch_queue_set_specific y dispatch_get_specific manualmente - No tengo las métricas sobre eso.

#import <libkern/OSAtomic.h> BOOL dispatch_is_on_queue(dispatch_queue_t queue) { int key; static int32_t incrementer; CFNumberRef value = CFBridgingRetain(@(OSAtomicIncrement32(&incrementer))); dispatch_queue_set_specific(queue, &key, value, nil); BOOL result = dispatch_get_specific(&key) == value; dispatch_queue_set_specific(queue, &key, nil, nil); CFRelease(value); return result; }