2

我认为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方法的完成处理程序,瞧,它可以在没有显式主线程块的情况下工作!

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

4

1 回答 1

2

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

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

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

于 2017-09-28T11:01:08.767 回答