J'ai un rappel qui peut provenir de n'importe quel fil. Lorsque je reçois ce rappel, je voudrais effectuer une certaine tâche sur le thread principal.
Dois-je vérifier si je suis déjà sur le fil principal - ou y a-t-il une pénalité en n'effectuant pas cette vérification avant d'appeler le code ci-dessous?
dispatch_async(dispatch_get_main_queue(), ^{
// do work here
});
Réponses:
Non, vous n'avez pas besoin de vérifier si vous êtes déjà sur le fil principal. En répartissant le bloc dans la file d'attente principale, vous planifiez simplement le bloc à exécuter en série sur le thread principal, ce qui se produit lorsque la boucle d'exécution correspondante est exécutée.
Si vous êtes déjà sur le thread principal, le comportement est le même: le bloc est planifié et exécuté lorsque la boucle d'exécution du thread principal est exécutée.
la source
async
renvoyé dans la file d'attente principale, il sera exécuté, mais cela peut perturber le calendrier prévu de vos actions . Par exemple, le code de l'interface utilisateurviewDidLoad()
ne s'exécute qu'après l'affichage initial de la vue .Pour le cas de répartition asynchrone que vous décrivez ci-dessus, vous ne devriez pas avoir besoin de vérifier si vous êtes sur le thread principal. Comme l'indique Bavarious, cela sera simplement mis en file d'attente pour être exécuté sur le thread principal.
Cependant, si vous essayez de faire ce qui précède à l'aide de a
dispatch_sync()
et que votre rappel est sur le thread principal, votre application se bloquera à ce stade. Je décris cela dans ma réponse ici , car ce comportement m'a surpris lors du déplacement de code-performSelectorOnMainThread:
. Comme je le mentionne ici, j'ai créé une fonction d'aide:qui exécutera un bloc de manière synchrone sur le thread principal si la méthode dans laquelle vous vous trouvez n'est pas actuellement sur le thread principal, et exécute simplement le bloc en ligne s'il l'est. Vous pouvez utiliser une syntaxe comme celle-ci pour l'utiliser:
la source
dispatch_set_specific()
cela aiderait dans le cas que vous décrivez: stackoverflow.com/a/12806754/19679 .Comme les autres réponses mentionnées, dispatch_async du thread principal est très bien.
Cependant, selon votre cas d'utilisation, il existe un effet secondaire que vous pouvez considérer comme un inconvénient: puisque le bloc est planifié dans une file d'attente, il ne s'exécutera pas tant que le contrôle ne reviendra pas à la boucle d'exécution, ce qui aura pour effet de retarder l'exécution de votre bloc.
Par exemple,
Imprime:
Pour cette raison, si vous vous attendiez à ce que le bloc s'exécute entre les NSLog externes, dispatch_async ne vous aiderait pas.
la source
Non, vous n'avez pas besoin de vérifier si vous êtes dans le fil principal. Voici comment vous pouvez le faire dans Swift:
Il est inclus en tant que fonction standard dans mon référentiel, consultez-le: https://github.com/goktugyil/EZSwiftExtensions
la source