1. ホーム
  2. ios

[解決済み] iPhone - Grand Central Dispatch メインスレッド

2022-05-09 18:37:18

質問

私は自分のアプリケーションでGrand Central Dispatchをうまく使っていますが、このようなものを使うことの本当の利点は何なのでしょうか。

dispatch_async(dispatch_get_main_queue(), ^{ ... do stuff

あるいは

dispatch_sync(dispatch_get_main_queue(), ^{ ... do stuff

つまり、どちらの場合も、アプリが実行されているメインスレッドで実行されるブロックを発行していることになり、これでは負荷を軽減することはできません。最初のケースでは、ブロックがいつ実行されるかを制御することはできません。ブロックを発射してから0.5秒後に実行されるケースを見たことがあります。2つ目のケースは、以下のような感じです。

[self doStuff];

ということですよね?

皆さんはどう思われますか。

解決方法は?

メインキューへのブロックのディスパッチは、通常、バックグラウンドの処理が終了したことを知らせるために、バックグラウンドのキューから行われます。

- (void)doCalculation
{
    //you can use any string instead "com.mycompany.myqueue"
    dispatch_queue_t backgroundQueue = dispatch_queue_create("com.mycompany.myqueue", 0);

    dispatch_async(backgroundQueue, ^{
        int result = <some really long calculation that takes seconds to complete>;

        dispatch_async(dispatch_get_main_queue(), ^{
            [self updateMyUIWithResult:result];
        });    
    });
}

このケースでは、バックグラウンドのキューで長時間の計算を行っており、計算が完了したときにUIを更新する必要があります。UIの更新は通常メインキューから行う必要があるので、2つ目のネストした dispatch_async を使ってメインキューに 'signal' を送り返します。

メインキューにディスパッチして戻したい例は他にもあるでしょうが、一般的にはこの方法、つまりバックグラウンドキューにディスパッチするブロックの中にネストして行われます。

  • バックグラウンド処理終了 -> UI更新
  • バックグラウンドキューで処理されたデータチャンク -> 次のチャンクを開始するためにメインキューにシグナルを送る。
  • バックグラウンドキューのネットワークデータ受信 -> メッセージが到着したことをメインキューに通知します。
  • などなど

メインキューにディスパッチしたい理由としては から メイン・キューは... まあ、一般的にはありえないことですが、考えられるのは、次に実行ループを回るときに行う作業をスケジュールするために行うことでしょう。