サーチ…


前書き

関連トピック: グランドセントラルディスパッチ

構文

  • dispatch_async - 別のキューにコードブロックを実行し、現在のキューを停止しません。キューがdispatch_asyncが呼び出されたスレッドと異なるスレッドにある場合、ブロック内のコードは実行され、dispatch_asyncの後のコードも実行されます
  • dispatch_syncは-別キュー内のコードのブロックを実行し、現在のキューを停止しません。キューがdispatch_asyncが呼び出されたスレッドとは異なるスレッド上にある場合、ブロック内のコードが実行され、メソッドが呼び出されたスレッドの実行は終了後のみ再開されます

パラメーター

キューディスパッチブロック内のコードが実行されるキューキューはスレッドと似ていますが(まったく同じではありません)。異なるキュー内のコードを並行して実行することができます。 dispatch_get_main_queueを使用してメインスレッドのキューを取得する新しいキューを作成し、新しいスレッドを作成するには、 dispatch_queue_create("QUEUE_NAME", DISPATCH_QUEUE_CONCURRENT)ます。最初のパラメータは、ブロックの実行中に一時停止するとデバッガに表示されるキューの名前です。 2番目のパラメータは、複数のdispatch_asyncまたはdispatch_sync呼び出しで同じキューを使用しない場合は重要ではありません。別のブロックが同じキューに置かれたときに何が起こるかを記述します。 DISPATCH_QUEUE_CONCURRENTは両方のブロックを同時に実行させますが、 DISPATCH_QUEUE_SERIALは最初のブロックが終了するまで2番目のブロックを待機させます
ブロックこのブロックのコードはキューqueue実行されqueue 。実行したいコードをここの別のキューに入れてください。便利なヒント:Xcodeでこれを記述していて、ブロック引数の周りに青いアウトラインがある場合は、引数をダブルクリックするとXcodeによって自動的に空のブロックが作成されます(これは関数またはメソッドのすべてのブロック引数に適用されます)

備考

キューを使用するときに発生する別のスレッドで何かを行うときは、常にスレッドの安全性を維持することが重要です。いくつかのメソッド、特にUIViewのメソッドは、メインスレッド以外のスレッドでは動作しない可能性があります。また、この変更を考慮しない限り、メインスレッドでも使用されているもの(変数、プロパティなど)を変更しないようにしてください

同時にコードを実行する - 他のコードを実行している間にコードを実行する

何か他のことを行いながら(この場合は "Foo"を記録する)、実行中に実行したいとします( "Bar"を記録する)。通常、並行性を使用しない場合、これらのアクションの1つは完全に実行され、もう1つの実行は完全に終了した後にのみ実行されます。しかし、並行処理を使用すると、両方のアクションを同時に実行することができます。

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

これは "Foo"を100回ログし、ログするたびに100ms休止しますが、これはすべて別のスレッドで行います。 Fooがログされている間、 "Bar"も50ms間隔で同時にログに記録されます。理想的には、 "Foo"と "Bars"が混在した出力を見るべきです

メインスレッドで実行する

非同期にタスクを実行する場合、通常は、コードがメインスレッド上で実行されるようにする必要があります。たとえば、REST APIを非同期的にヒットさせたいが、その結果を画面上のUILabelに入れることができます。 UILabelを更新する前に、コードがメインスレッドで実行されていることを確認する必要があります。

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

画面上のビューを更新するたびに、常にメインスレッドで実行していることを確認してください。そうしないと、未定義の動作が発生する可能性があります。

ディスパッチグループ - 完了した他のスレッドを待っています。

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

アップデート1. 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
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow