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

编辑: 正如罗布建议,我用这种方法[NSThread isMainThread]检查,看看在哪个线程的代码被执行。它明确返回true,以确认我在主线程中,但奇怪的是,没有明确地将我的setImage方法调度到主队列,代码不起作用。另外,我试着将我的代码移动到选取器的dismiss方法的完成处理程序,看起来它没有明确的主线程块工作!

仍困惑于为什么这种行为是这样的......

+0

好的在这里见到你,我不知道问题阅读 DOC: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

是你的导航控制器上的按钮?如果是这样,也许选择器的导航控制器会干扰这一点,并且调度异步将其推迟到足以达到您期望的效果。推迟一些用户界面更新是一个古老而笨拙的技巧。 – Rob

+0

是的,该按钮位于导航控制器内部,我从'UIAlertAction'处理程序块中呈现选择器。这可能是一个问题吗?我想这不应该,因为'isMainThread'无论如何返回'true'。 –

相关问题