didFinishPickingMediaWithInfo 是否在后台线程中被调用?

Does didFinishPickingMediaWithInfo get called in background thread?

我认为 UIImagePickerController 委托方法(或任何 UIKit 委托方法)在主线程中被调用。但是在这里,当从图库或相机中选取图像时,didFinishPickingMediaWithInfo 方法似乎并没有被调用,UIKit 委托方法必须在主线程上调用,对吧?显式分派到主线程工作。 Apple文档中也没有提到这一点。

-(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 委托方法都在主线程上调用?或者一些在非主线程中被调用?为什么我们认为没有必要将我们的代码分派到主线程,但最终这样做会使事情正常进行,为什么会出现这种不一致?如果有人知道答案,请澄清。

编辑: 正如 Rob 所建议的,我检查了这个方法 [NSThread isMainThread] 以查看代码在哪个线程中执行。它清楚地返回 true 以确认我在主线程中,但奇怪的是没有将我的 setImage 方法显式分派到主队列,代码不起作用。此外,我尝试将我的代码移动到选择器的 dismiss 方法的完成处理程序,瞧,它在没有显式主线程块的情况下工作!

仍然对为什么会这样表现感到困惑...

我测试的时候是在主线程调用的。我建议检查 [NSThread isMainThread] 以确认(或者,在 Swift、dispatchPrecondition(condition: .onQueue(.main))Thread.isMainThread 中)。在我的测试中,它在主线程上。

如果它不是主线程 (!),我会检查你在哪里展示它,以确保你是从主线程展示它的。

我想不出在后台线程上调用的任何 UI 相关委托方法。对于非 UI 委托方法,有很多不使用主线程,但是 UI-centric API 像这样使用主线程。