Zoeken…


Invoering

Verwant onderwerp: Grand Central-verzending

Syntaxis

  • dispatch_async - voert een codeblok uit in een afzonderlijke wachtrij en stopt de huidige wachtrij niet. Als de wachtrij zich op een andere thread bevindt dan degene die dispatch_async is aangeroepen, wordt de code in het blok uitgevoerd, terwijl code na dispatch_async ook wordt uitgevoerd
  • dispatch_sync - Voert een codeblok in een afzonderlijke wachtrij, en stopt de huidige rij. Als de wachtrij zich op een andere thread bevindt dan degene die dispatch_async is aangeroepen, wordt de code in het blok uitgevoerd en wordt de uitvoering op de thread waar de methode werd aangeroepen pas hervat nadat deze is voltooid

parameters

wachtrij De wachtrij waarin de code in het verzendblok wordt uitgevoerd. Een wachtrij is als (maar niet exact hetzelfde als) een thread; code in verschillende wachtrijen kan parallel worden uitgevoerd. Gebruik dispatch_get_main_queue om de wachtrij voor de dispatch_queue_create("QUEUE_NAME", DISPATCH_QUEUE_CONCURRENT) Gebruik een dispatch_queue_create("QUEUE_NAME", DISPATCH_QUEUE_CONCURRENT) om een nieuwe wachtrij te maken die op zijn beurt een nieuwe thread maakt. De eerste parameter is de naam van de wachtrij, die wordt weergegeven in de debugger als u pauzeert terwijl het blok nog steeds actief is. De tweede parameter maakt niet uit, tenzij u dezelfde wachtrij wilt gebruiken voor meerdere aanroepen dispatch_async of dispatch_sync . Het beschrijft wat er gebeurt wanneer een ander blok in dezelfde wachtrij wordt geplaatst; DISPATCH_QUEUE_CONCURRENT zorgt ervoor dat beide blokken tegelijkertijd worden uitgevoerd, terwijl DISPATCH_QUEUE_SERIAL het tweede blok laat wachten tot het eerste blok is voltooid
blok Code in dit blok wordt uitgevoerd in de queue . plaats de code die u wilt uitvoeren hier in de afzonderlijke wachtrij. Een handige tip: als u dit in Xcode schrijft en het blokargument heeft de blauwe omtrek, dubbelklik op het argument en Xcode maakt automatisch een leeg blok (dit is van toepassing op alle blokargumenten in een functie of methode)

Opmerkingen

Wanneer u iets op een afzonderlijke thread doet, wat gebeurt wanneer u wachtrijen gebruikt, is het belangrijk om de threadveiligheid te handhaven. Sommige methoden, met name voor UIView 's, werken mogelijk niet en / of crashen op andere threads dan de hoofdthread. Zorg er ook voor dat u niets (variabelen, eigenschappen, enz.) Verandert dat ook in de hoofdthread wordt gebruikt, tenzij u rekening houdt met deze wijziging

Code tegelijkertijd uitvoeren - Code uitvoeren terwijl andere code wordt uitgevoerd

Stel dat u in actie wilt uitvoeren (in dit geval "Foo"), terwijl u iets anders doet ("Bar"). Normaal gesproken, als u geen gelijktijdigheid gebruikt, wordt een van deze acties volledig uitgevoerd en wordt de andere run pas uitgevoerd nadat deze volledig is voltooid. Maar met gelijktijdigheid kunt u beide acties tegelijkertijd uitvoeren:

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);
}

Dit registreert 100 keer "Foo" en pauzeert 100 ms elke keer dat het logt, maar het doet dit allemaal op een aparte thread. Terwijl Foo wordt geregistreerd, wordt "Bar" tegelijkertijd met intervallen van 50 ms vastgelegd. In het ideale geval ziet u een uitvoer met "Foo" s en "Bars" door elkaar

Uitvoeren op de hoofdthread

Bij het asynchroon uitvoeren van taken bestaat er meestal een behoefte om ervoor te zorgen dat een stukje code op de hoofdthread wordt uitgevoerd. U wilt bijvoorbeeld asynchroon een REST API raken, maar het resultaat in een UILabel op het scherm plaatsen. Voordat u het UILabel bijwerkt, moet u ervoor zorgen dat uw code op de hoofdthread wordt uitgevoerd:

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 = //....
    });
}

Wanneer u weergaven op het scherm bijwerkt, zorg er dan altijd voor dat u dit doet via de hoofdthread, anders kan er ongedefinieerd gedrag optreden.

Verzendgroep - wachten op andere threads voltooid.

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");
});

Update 1. Swift 3-versie.

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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow