Recherche…


Introduction

Rubrique connexe: Dispatch Grand Central

Syntaxe

  • dispatch_async - Exécute un bloc de code dans une file d'attente séparée et n'arrête pas la file d'attente en cours. Si la file d'attente se trouve sur un thread différent de celui sur lequel on a appelé dispatch_async, le code du bloc s'exécutera alors que le code est exécuté après l'exécution de dispatch_async
  • dispatch_sync - exécute un bloc de code dans une file d' attente séparée, et ne se limite la file d' attente en cours. Si la file d'attente se trouve sur un thread différent de celui sur lequel on a appelé dispatch_async, le code du bloc s'exécutera et son exécution sur le thread où la méthode a été appelée ne reprendra qu'après la fin

Paramètres

queue La file d'attente dans laquelle le code dans le bloc de distribution sera exécuté. Une file d'attente est comme (mais pas exactement comme) un thread; le code dans différentes files d'attente peut s'exécuter en parallèle. Utilisez dispatch_get_main_queue pour obtenir la file d'attente du thread principal Pour créer une nouvelle file d'attente, qui à son tour crée un nouveau thread, utilisez dispatch_queue_create("QUEUE_NAME", DISPATCH_QUEUE_CONCURRENT) . Le premier paramètre est le nom de la file d'attente, qui est affiché dans le débogueur si vous faites une pause pendant que le bloc est toujours en cours d'exécution. Le second paramètre n'a pas d'importance à moins que vous ne souhaitiez utiliser la même file d'attente pour plusieurs appels à dispatch_async ou dispatch_sync . Il décrit ce qui se passe lorsqu'un autre bloc est placé dans la même file d'attente. DISPATCH_QUEUE_CONCURRENT provoquera l'exécution des deux blocs en même temps, tandis que DISPATCH_QUEUE_SERIAL fera attendre le second bloc pour terminer le deuxième bloc
bloc Le code dans ce bloc s'exécutera dans la file d' queue la file d' queue ; mettre le code que vous souhaitez exécuter dans la file d'attente séparée ici. Un conseil utile: si vous écrivez ceci dans Xcode et que l'argument de bloc a le contour bleu, double-cliquez sur l'argument et Xcode créera automatiquement un bloc vide (cela s'applique à tous les arguments de bloc de n'importe quelle fonction ou méthode)

Remarques

Chaque fois que vous faites quelque chose sur un thread séparé, ce qui se produit lors de l'utilisation de files d'attente, il est important de maintenir la sécurité des threads. Certaines méthodes, en particulier celles de UIView s, peuvent ne pas fonctionner et / ou ne peuvent pas tomber en panne sur des threads autres que le thread principal. Veillez également à ne rien modifier (variables, propriétés, etc.) qui est également utilisé sur le thread principal, à moins que vous ne teniez compte de cette modification.

Exécution simultanée du code - Exécution du code lors de l'exécution d'un autre code

Supposons que vous souhaitiez effectuer une action (dans ce cas, vous connectez "Foo"), tout en faisant autre chose (en enregistrant "Bar"). Normalement, si vous n'utilisez pas la simultanéité, l'une de ces actions va être entièrement exécutée et l'autre exécution ne sera exécutée qu'après avoir été complètement terminée. Mais avec la concurrence, vous pouvez exécuter les deux actions en même temps:

dispatch_async(dispatch_queue_create("Foo", DISPATCH_QUEUE_CONCURRENT), ^{
    for (int i = 0; i < 100; i++) {
        NSLog(@"Foo");
        usleep(100000);
    }
});

for (int i = 0; i < 100; i++) {
    NSLog(@"Bar");
    usleep(50000);
}

Cela va enregistrer "Foo" 100 fois, en faisant une pause de 100 ms à chaque fois qu'il se connecte, mais il fera tout cela sur un thread séparé. Pendant que Foo est en cours de connexion, "Bar" sera également enregistré dans des intervalles de 50 ms, en même temps. Vous devriez idéalement voir une sortie avec "Foo" et "Bars" mélangés ensemble

Exécution sur le thread principal

Lors de l'exécution asynchrone de tâches, il devient généralement nécessaire de s'assurer qu'un morceau de code est exécuté sur le thread principal. Par exemple, vous voudrez peut-être frapper une API REST de manière asynchrone, mais placez le résultat dans un UILabel à l'écran. Avant de mettre à jour le UILabel, vous devez vous assurer que votre code est exécuté sur le thread principal:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    //Perform expensive tasks
    //...

    //Now before updating the UI, ensure we are back on the main thread
    dispatch_async(dispatch_get_main_queue(), ^{
        label.text = //....
    });
}

Chaque fois que vous mettez à jour des vues à l'écran, assurez-vous toujours de le faire sur le thread principal, sinon un comportement indéfini pourrait se produire.

Dispatch group - en attente d'autres threads terminés.

dispatch_group_t preapreWaitingGroup = dispatch_group_create();

dispatch_group_enter(preapreWaitingGroup);
[self doAsynchronousTaskWithComplete:^(id someResults, NSError *error) { 
    // Notify that this task has been completed.
    dispatch_group_leave(preapreWaitingGroup);  
}]

dispatch_group_enter(preapreWaitingGroup);
[self doOtherAsynchronousTaskWithComplete:^(id someResults, NSError *error) { 
    dispatch_group_leave(preapreWaitingGroup);  
}]

dispatch_group_notify(preapreWaitingGroup, dispatch_get_main_queue(), ^{
    // This block will be executed once all above threads completed and call dispatch_group_leave
    NSLog(@"Prepare completed. I'm readyyyy");
});

Mise à jour 1. Version Swift 3.

let prepareGroup = DispatchGroup()
prepareGroup.enter()
doAsynchronousTaskWithComplete() { (someResults, error) in
    // Notify that this task has been completed.
    prepareGroup.leave()
}

prepareGroup.enter()
doOtherAsynchronousTaskWithComplete() { (someResults, error) in
    // Notify that this task has been completed.
    prepareGroup.leave()
}

prepareGroup.notify(queue: DispatchQueue.main) {
    // This block will be executed once all above threads completed and call dispatch_group_leave
    print("Prepare completed. I'm readyyyy")
}


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow