Suche…


Einführung

Verwandte Themen: Grand Central Dispatch

Syntax

  • dispatch_async - Führt einen Codeblock in einer separaten Warteschlange aus und stoppt die aktuelle Warteschlange nicht. Wenn sich die Warteschlange in einem anderen Thread befindet als der, für den dispatch_async aufgerufen wurde, wird der Code im Block ausgeführt, während der Code nach dem dispatch_async ebenfalls ausgeführt wird
  • dispatch_sync - Führt einen Codeblock in einer separaten Warteschlange und die aktuelle Warteschlange nicht zu stoppen. Wenn sich die Warteschlange in einem anderen Thread befindet als der, für den dispatch_async aufgerufen wurde, wird der Code im Block ausgeführt, und die Ausführung des Threads, in dem die Methode aufgerufen wurde, wird erst wieder aufgenommen, wenn sie abgeschlossen ist

Parameter

Warteschlange Die Warteschlange, in der der Code im Dispatch-Block ausgeführt wird. Eine Warteschlange ist (aber nicht genau wie ein Thread). Code in verschiedenen Warteschlangen kann parallel ausgeführt werden. Verwenden Sie dispatch_get_main_queue , um die Warteschlange für den Hauptthread dispatch_queue_create("QUEUE_NAME", DISPATCH_QUEUE_CONCURRENT) Zum Erstellen einer neuen Warteschlange, die wiederum einen neuen Thread erstellt, verwenden Sie dispatch_queue_create("QUEUE_NAME", DISPATCH_QUEUE_CONCURRENT) . Der erste Parameter ist der Name der Warteschlange, der im Debugger angezeigt wird, wenn Sie anhalten, während der Block noch läuft. Der zweite Parameter ist unwichtig, es sei denn, Sie möchten dieselbe Warteschlange für mehrere dispatch_async oder dispatch_sync Aufrufe verwenden. Es beschreibt, was passiert, wenn ein anderer Block in dieselbe Warteschlange gestellt wird. DISPATCH_QUEUE_CONCURRENT bewirkt, dass beide Blöcke gleichzeitig ausgeführt werden, während DISPATCH_QUEUE_SERIAL den zweiten Block auf den Abschluss des ersten Blocks warten lässt
Block Code in diesem Block wird in der queue . Geben Sie hier den Code ein, den Sie in der separaten Warteschlange ausführen möchten. Ein hilfreicher Tipp: Wenn Sie dies in Xcode schreiben und das Blockargument blau umrahmt ist, doppelklicken Sie auf das Argument, und Xcode erstellt automatisch einen leeren Block (dies gilt für alle Blockargumente in einer Funktion oder Methode).

Bemerkungen

Wenn Sie etwas in einem separaten Thread tun, was bei der Verwendung von Warteschlangen der Fall ist, ist es wichtig, die Thread-Sicherheit zu gewährleisten. Einige Methoden, insbesondere für UIView , funktionieren möglicherweise nicht und stürzen nicht in anderen Threads als dem Haupt-Thread ab. Stellen Sie außerdem sicher, dass Sie nichts (Variablen, Eigenschaften usw.) ändern, das auch im Hauptthread verwendet wird, es sei denn, Sie berücksichtigen diese Änderung

Gleichzeitiger Ausführen von Code - Ausführen von Code, während anderer Code ausgeführt wird

Angenommen, Sie möchten eine Aktion ausführen (in diesem Fall "Foo" protokollieren), während Sie etwas anderes tun ("Balken" protokollieren). Wenn Sie keine Parallelität verwenden, wird eine dieser Aktionen normalerweise vollständig ausgeführt, und der andere Lauf wird erst ausgeführt, wenn er vollständig abgeschlossen ist. Mit Parallelität können Sie jedoch beide Aktionen gleichzeitig ausführen:

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

Dadurch wird "Foo" 100-mal protokolliert und jedes Mal, wenn es protokolliert, für 100 ms angehalten. Dies geschieht jedoch in einem separaten Thread. Während der Foo wird "Bar" gleichzeitig im 50-ms-Intervall protokolliert. Im Idealfall sollte eine Ausgabe mit "Foo" s und "Bars" gemischt angezeigt werden

Ausführung im Hauptthread

Wenn Aufgaben asynchron ausgeführt werden, muss normalerweise sichergestellt werden, dass im Haupt-Thread Code ausgeführt wird. Beispielsweise möchten Sie eine REST-API asynchron schlagen, das Ergebnis jedoch in einem UILabel auf dem Bildschirm anzeigen. Bevor Sie das UILabel aktualisieren, müssen Sie sicherstellen, dass Ihr Code im Hauptthread ausgeführt wird:

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

Wenn Sie Ansichten auf dem Bildschirm aktualisieren, stellen Sie immer sicher, dass Sie dies im Haupt-Thread tun, da andernfalls undefiniertes Verhalten auftreten kann.

Versandgruppe - Warten auf andere Threads abgeschlossen.

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 Version.

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
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow