2017-02-23 8 views
1

iOSのメインスレッドでUI関連の作業を実行する必要があります。 }uikitメソッドはメインスレッド上で実行されますか?

;)

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
UIImage *overlayImage = [self faceOverlayImageFromImage:_image]; 
dispatch_async(dispatch_get_main_queue(), ^{ 
    [self fadeInNewImage:overlayImage]; 
}); 

}:時々、私たちは、画像をダウンロードするようないくつかの非同期ジョブを実行する必要があり、我々は、おそらくdispatch_asyncを使用すると、ダウンロードが完了したら、我々はメインスレッドを取得し、このような何かのようにそれを表示するとき

しかし、我々はローカルにイメージをロードするとき、我々は通常、ちょうどメインスレッドにディスパッチすることなく、次の操作を行います。私の質問は、彼らがメインスレッド上で実行されることが保証されている

UIImageView *imageView = [[UIImageView alloc] initWithImage:@"myimage.png"]; 

?はいの場合、なぜdispatch_get_main_queue()を使用してディスパッチする必要がありますか?どうして私たちはメインスレッド上のすべての関連作業をディスパッチする必要はありませんか?

答えて

6

あなたは混乱しています。

特定のコールチェーンは、メインスレッドまたはバックグラウンドスレッドで実行されます。対処するコードのほとんどは、システムイベントを通じて呼び出され、メインスレッド上で実行されることが保証されています。コードがバックグラウンドスレッドから呼び出されるケースは限られています。そのような場合にのみ、呼び出しをメインスレッドにリダイレクトするコードでUIKit呼び出しをラップする必要があります。

View Controller関数、ボタンアクションなどは、常にメインスレッドで呼び出されます。システムがバックグラウンドスレッド上で何らかのメソッドを呼び出すと、それは十分に文書化されます。

補完ハンドラを使用する関数の中には、バックグラウンドスレッドで補完ハンドラを呼び出すものがあります。たとえば、NSURLSessionURLSession)クラスは、そのコンプリートハンドラとデリゲートメソッドをデリゲートキューに呼び出し、デフォルトではバックグラウンドスレッドになります。したがって、完了ハンドラをURLSessionのインスタンスに渡すときは、UIKitコードがdispatch_async()(Swift 3のDispatchQueue.main.async())または実行するメインスレッドにコードを渡す同様の方法で呼び出されるようにする必要があります。

+0

説明:ディスパッチを使用する必要がある理由は、*あなたがバックグラウンドスレッドを開始し、そのスレッドがUIを変更する必要があるためです。 UIの切り替えがUIスレッドへの切り替えを処理するコールバック(プログレスバーのsetProgressなど)を介して行われない限り、ディスパッチを使用する必要があります。 – ToolmakerSteve

1

ほとんどのUI関連のアクションは、正常に動作するためにメインスレッドで実行する必要があります。しかし、単にUI...クラスを使用するだけでは、それがメインスレッド上で確実に実行されることはありません。

それはプログラマーとしてのあなたの仕事です。バックグラウンドで(データのダウンロードや長時間実行されるタスクのような)何らかの操作を行い、その後UIを更新する必要がある場合は、メインスレッドでUIコードが完了していることを確認する必要があります。

UIImageインスタンスを作成すると、バックグラウンドスレッドで安全に作成できることに注意してください。それは安全です。

tl; dr - no、メインスレッドでは何も実行されません。そして、あなたがメインスレッド上にいない限り、メインスレッド上のすべてのUI関連の作業をディスパッチする必要があります。

関連する問題