[解決済み] dispatch_async(dispatch_get_main_queue(), ^{...}); は完了するまで待つのですか?
2022-02-16 19:56:15
質問
私のアプリでは、データ処理とUI更新からなる時間のかかる作業をメソッドで行いたいシナリオがあります。私のメソッドは次のようなものです。
- (void)doCalculationsAndUpdateUIs {
// DATA PROCESSING 1
// UI UPDATE 1
// DATA PROCESSING 2
// UI UPDATE 2
// DATA PROCESSING 3
// UI UPDATE 3
}
時間がかかるので、バックグラウンドスレッドでデータ処理を行いたいと思い、使ってみました。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL), ^{
しかし、データ処理とUI更新が同じメソッドで行われているため、UI更新のみをメインスレッドで行いたいと考えました。
dispatch_async(dispatch_get_main_queue(), ^{
最後に私のメソッドは次のようになります。
- (void)doCalculationsAndUpdateUIs {
// DATA PROCESSING 1
dispatch_async(dispatch_get_main_queue(), ^{
// UI UPDATE 1
});
/* I expect the control to come here after UI UPDATE 1 */
// DATA PROCESSING 2
dispatch_async(dispatch_get_main_queue(), ^{
// UI UPDATE 2
});
/* I expect the control to come here after UI UPDATE 2 */
// DATA PROCESSING 3
dispatch_async(dispatch_get_main_queue(), ^{
// UI UPDATE 3
});
}
これは本当に効果があるのだろうか?これは本当に良い方法なのでしょうか?これを実現するための最良の方法は何でしょうか?
追伸:この3つの作業は、すべて互いに関連しています。
EDITです。 みんな、ごめんね。私は 上記のコードに一行抜けがありました . 私の実際のコードは以下のようなものです。
- (void)doCalculationsAndUpdateUIs {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// DATA PROCESSING 1
dispatch_async(dispatch_get_main_queue(), ^{
// UI UPDATE 1
});
/* I expect the control to come here after UI UPDATE 1 */
// DATA PROCESSING 2
dispatch_async(dispatch_get_main_queue(), ^{
// UI UPDATE 2
});
/* I expect the control to come here after UI UPDATE 2 */
// DATA PROCESSING 3
dispatch_async(dispatch_get_main_queue(), ^{
// UI UPDATE 3
});
});
}
改めて、混乱させてしまったことを本当に申し訳なく思います。
解決方法は?
そのサンプルでやっている方法は良いやり方ではありません。
dispatch_async
は常に
非同期
. これは、すべてのUIブロックを同じキューにエンキューしているため、異なるブロックが順番に実行されますが、データ処理コードと並行して実行されるだけなのです。
更新を待たせたい場合は
dispatch_sync
の代わりに
// This will wait to finish
dispatch_sync(dispatch_get_main_queue(), ^{
// Update the UI on the main thread.
});
もう一つのアプローチは、ブロックをネストエンキューすることです。I はしないでしょう。 しかし、多段階ではお勧めできません。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Background work
dispatch_async(dispatch_get_main_queue(), ^{
// Update UI
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Background work
dispatch_async(dispatch_get_main_queue(), ^{
// Update UI
});
});
});
});
UIの更新を待つ必要がある場合は、同期バージョンを使用する必要があります。バックグラウンドスレッドがメインスレッドを待っていても、まったく問題ありません。UIの更新は非常に速いはずです。
関連
-
[解決済み】Xcode 10.2.1 Command PhaseScriptExecutionが0以外の終了コードで失敗した。
-
[解決済み】iOS 9.0より前のUIStackView
-
[解決済み] Xcodeエラー:SDK 'iOS 10.0'の製品タイプ 'Application'では、コード署名が必要です。
-
[解決済み] swiftで「floor」が使用できない
-
[解決済み] iPhoneが使用できません。デバイスを再接続してください
-
[解決済み] UITabBar アイコンが正しく表示されない
-
[解決済み] Objective C - 値で渡す、参照で渡す
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] wait()とsleep()の違いについて
-
[解決済み] シンクロナイズド」とはどういう意味ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】arm64アーキテクチャの未定義シンボルについて
-
[解決済み】 libc++abi.dylib: NSException 型のキャッチできない例外で終了する (lldb)
-
[解決済み】クラスは両方で実装されており、どちらかが使用されることになります。どちらが未定義か
-
[解決済み] ウィンドウ階層にないビューを持つUIViewControllerでUIViewControllerを表示しようとする
-
[解決済み] swiftで「floor」が使用できない
-
[解決済み] iPhoneが使用できません。デバイスを再接続してください
-
[解決済み] Xcodeで "No such module "というエラーが出るが、フレームワークはある
-
[解決済み] SwiftでUIColor patternImageを使用して画像を中心からタイル状に配置する方法
-
[解決済み] 条件付きバインディング:letエラーの場合 - 条件付きバインディングのイニシャライザーはOptional型でなければならない
-
[解決済み] アラート "デバッグを続けるには、開発者ツールへのアクセスが他のプロセスの制御を必要とします。これを許可するにはパスワードを入力してください。