Récemment, j'ai eu besoin d'une fonction que je pouvais utiliser pour garantir l'exécution synchrone d'un bloc donné sur une file d'attente de distribution série particulière. Il était possible que cette fonction partagée soit appelée à partir d'un bloc déjà en cours d'exécution sur cette file d'attente. J'avais donc besoin de vérifier ce cas afin d'éviter un blocage à partir d'une répartition synchrone sur la même file d'attente.
J'ai utilisé un code comme le suivant pour faire cela :
void runSynchronouslyOnVideoProcessingQueue(void (^block)(void))
{
dispatch_queue_t videoProcessingQueue = [GPUImageOpenGLESContext sharedOpenGLESQueue];
if (dispatch_get_current_queue() == videoProcessingQueue)
{
block();
}
else
{
dispatch_sync(videoProcessingQueue, block);
}
}
Cette fonction repose sur l'utilisation de dispatch_get_current_queue()
pour déterminer l'identité de la file d'attente sur laquelle cette fonction est exécutée et la compare à la file d'attente cible. S'il y a une correspondance, il sait qu'il faut simplement exécuter le bloc en ligne sans le dispatch vers cette file d'attente, car la fonction y est déjà exécutée.
J'ai entendu des choses contradictoires sur le fait qu'il était approprié ou non d'utiliser dispatch_get_current_queue()
pour faire des comparaisons comme celle-ci, et je vois cette formulation dans les en-têtes :
Recommandé uniquement à des fins de débogage et de journalisation :
Le code ne doit pas faire d'hypothèses sur la file d'attente retournée, à moins qu'il ne s'agisse de l'une des files d'attente globales ou d'une file d'attente que le code a lui-même créée par le code. Le code ne doit pas supposer que l'exécution synchrone sur une queue est à l'abri des blocages si cette file n'est pas celle renvoyée par la commande dispatch_get_current_queue().
En outre, dans iOS 6.0 (mais pas encore dans Mountain Lion), les en-têtes GCD indiquent désormais que cette fonction est obsolète.
Il semble que je ne devrais pas utiliser cette fonction de cette manière, mais je ne suis pas sûr de ce que je devrais utiliser à sa place. Pour une fonction comme celle ci-dessus qui vise la file d'attente principale, je pourrais utiliser [NSThread isMainThread]
Mais comment puis-je vérifier si je fonctionne sur l'une de mes files d'attente série personnalisées afin d'éviter un blocage ?