1

UIImagePickerControllerデリゲートメソッド(またはUIKitデリゲートメソッド)がメインスレッドで呼び出されると考えました。しかしギャラリーやカメラから画像を取り出すときに、didFinishPickingMediaWithInfoメソッドが呼び出されないようで、UIKitデリゲートメソッドをメインスレッドの右に呼び出す必要がありますか?メインスレッドの作業に明示的にディスパッチします。 Appleのドキュメントにもこれに関する記述はありません。didFinishPickingMediaWithInfoはバックグラウンドスレッドで呼び出されますか?

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString* ,id> *)info{ 

    uploadImage = info[UIImagePickerControllerOriginalImage]; // Set selected image    
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self.leftButton setImage:[UIImage imageNamed:@"image_attach.png"] 
         forState:UIControlStateNormal]; 
    }); 

    // The following does not work. 
    //[self.leftButton setImage:[UIImage imageNamed:@"image_attach.png"] 
        //forState:UIControlStateNormal]; 
} 

ボトムライン、すべてのUIKitデリゲートメソッドは、メインスレッドで呼び出されますか?または、非メインスレッドで呼び出されるものがありますか?なぜこの矛盾は、私たちのコードをメインスレッドにディスパッチする必要はないと信じていますが、最終的にはそれが機能しますか?誰かが答えを知っていれば、明確にしてください。

EDIT:ロブによって示唆されるように 、私はコードが実行されますどのスレッドで確認するには、この方法[NSThread isMainThread]で確認。明らかに私がメインスレッドにあることを確認するためにtrueを返しましたが、間違いなくsetImageメソッドをメインキューに明示的にディスパッチせずに、コードは機能しません。また、ピッカーのdismissメソッドの補完ハンドラにコードを移動しようとしましたが、明白なメインスレッドブロックなしで動作します。

まだ混乱し、これは次のように動作している理由について...

+0

ここであなたを見るために良い、私は質問についてはよく分からないです ドキュメントをお読みください。https://developer.apple.com/documentation/uikit#//apple_ref/doc/uid/TP40006955-CH1-SW1 – karthikeyan

+0

@karthikeyanグッドあなたにも会いましょう。はい、私はそれを認識しています。しかし、私は具体的には、UIKitデリゲートメソッドがメインスレッドまたはバックグラウンドスレッドで呼び出されるかどうかを知りたい。ドキュメントごとに –

+0

あなたのアプリのメインスレッドまたはメインディスパッチキューからのUIKitクラスのみ – karthikeyan

答えて

1

私はそれをテストしたとき、それはメインスレッドで呼び出されました。確認するために[NSThread isMainThread]を確認することをおすすめします(または、SwiftでdispatchPrecondition(condition: .onQueue(.main))またはThread.isMainThread)。私のテストでは、それはメインスレッドにあった。

メインスレッド(!)でない場合は、メインスレッドから提示したかどうかを確認するために、どこに表示するかを確認します。

バックグラウンドスレッドで呼び出されるUI関連のデリゲートメソッドは考えられません。非UIデリゲートメソッドの場合、メインスレッドを使用しないものがたくさんありますが、このようなUI中心のAPIはメインスレッドを使用します。

+0

'[NSThread isMainThread]'でチェックし、 'YES'を返します。しかし、私の 'setImage'メソッドをメインキューに明示的にディスパッチしなければ、動作しません。奇妙な.... –

+0

は、ナビゲーションコントローラ上のボタンですか?そうであれば、おそらくピッカーのナビゲーションコントローラがそれを妨害している可能性があります。ディスパッチ非同期は、あなたが望む結果を達成するのに十分な時間を延期しています。これは、いくつかのUI更新を延期するための古い、クルジのトリックです。 – Rob

+0

はい、ボタンはナビゲーションコントローラ内にあり、 'UIAlertAction'ハンドラブロックからピッカーを提示しています。それは問題になることができますか?とにかく 'isMainThread'が' true'を返すので、そうではないはずです。 –

関連する問題