2017-07-02 8 views
0

は、UIの更新を行う除外explicitiy私のUIの更新がdispatch_async(dispatch_get_main_queueを()コメントアウトするとこの質問https://stackoverflow.com/a/23155684/1898829は、なぜ私はメインスレッドへの復帰

[[session dataTaskWithRequest:request 
      completionHandler:^(NSData *data, NSURLResponse *response, 
           NSError *error) { 
       if (data != nil) { 
        NSDictionary *responseDictionary = 
        [NSJSONSerialization JSONObjectWithData:data 
                options:kNilOptions 
                 error:&error]; 
//      dispatch_async(dispatch_get_main_queue(), ^{ 
          CarListModel *carListModel = [[CarListModel alloc] 
                  initWithArray:responseDictionary[@"placemarks"]]; 
          completion(carListModel, error); 
//      }); 
        } else { 
         dispatch_async(dispatch_get_main_queue(), ^{ 
          completion(nil, error); 
         }); 
        } 
       }] resume]; 

に応じてメインスレッド上で実行する必要がありません、^{私のアプリは以前と同じように動作します。テーブルビューが更新され、アクティビティインジケータが停止する

このコンプリートブロックは、ビューコントローラに送られる完了ブロックを持つビューモデルに移動します。メインスレッドに戻る必要があります。

はなぜUIがブロックされていませんか、あなたはUIの更新がメインスレッド上で実行する必要があることを正しい私は明示的に

dispatch_async(dispatch_get_main_queue(), ^{ 
+0

あなたがメインスレッドに「帰国」されていません。メインスレッドは並行して実行されます。 '-dataTaskWithRequest'は、anthoerスレッド上で実行されるキューを使用します。したがって、メインスレッドをブロックすることはできません。メインスレッドのコードのみがメインスレッドをブロックできます。 –

+0

私のUIの変更はメインスレッドで行われていないのですか?メインスレッドで処理されているのはなぜですか? – user1898829

+0

完了ハンドラをメインキューへのディスパッチの外で実行すると、そのスレッドはメインスレッドの外側で実行されます。私は補完ハンドラのコードを知らないので、どのキューで何が行われるのかは言えません。 –

答えて

1

でそれを設定せずに、メインスレッドに戻ることが可能です。あなたは、メインスレッドでそれをやっていないと何も起こらないと信じていると誤解されています。それだけであれば。あなたがメインスレッドではないUIの更新を行う場合、アプリは何時でも奇妙な予期しない方法で失敗する可能性があります。これは、数分後にクラッシュする可能性があることを意味します。アニメーションが突然動作を停止する可能性があります。ビューはランダムに消えたり出現したりすることがあります。ナビゲーションバーが外れている可能性があります。つまり、動作は定義されていません。あなたが誤ってバックグラウンドスレッドから呼び出されるかもしれない方法を持っている場合は、バックグラウンドスレッド

2)からUIを更新する際

したがって、あなたは

1)いつものようなものでそれらを保護し、dispatch_async(dispatch_get_main_queue(), ^{を使用する必要があります。

if (![NSThread mainThread]) { 
    // log to crash reporter without crashing 
    NSError* error = [NSError errorWithDomain:@"accessing UI outside of main thread" code:-1 userInfo:nil]; 
    [[Crashlytics sharedInstance] recordError:error withAdditionalUserInfo:@{@"file":__FILE__, @"line":@(__LINE__)}]; 
    return; 
} 
関連する問題