I thought that the UIImagePickerController
delegate methods (or any UIKit
delegate method) get called in the main thread. But here, when picking image from gallery or camera, the didFinishPickingMediaWithInfo
method does not seem to get called in one, and UIKit delegate methods must be called on main thread right? Dispatching explicitly to main thread works. There are no mentions about this in the Apple documentation as well.
-(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];
}
Bottom line, do all UIKit delegate methods get called on main thread? Or some get called in non-main thread? Why this inconsistency where we BELIEVE that there is no necessity to dispatch our code to main thread, but in the end doing that makes things work? If someone knows the answer please clarify.
EDIT:
As suggested by Rob, I checked with this method [NSThread isMainThread]
to see in which thread the code gets executed. It clearly returned true
to confirm that I am in the main thread, but strangely without dispatching my setImage
method to main queue explicitly, the code does not work. Also, I tried moving my code to the picker's dismiss
method's completion handler, voila it works without an explicit main thread block!
Still confused on why this is behaving like this...
When I tested it, it was called on the main thread. I'd suggest checking [NSThread isMainThread]
to confirm (or, in Swift, dispatchPrecondition(condition: .onQueue(.main))
or Thread.isMainThread
). In my test, it was on the main thread.
If it's not the main thread (!), I'd check where you present it, to make sure you presented it from the main thread.
I can't think of any UI-related delegate methods that are called on a background thread. For non UI delegate methods, there are plenty that don't use the main thread, but UI-centric API like this use the main thread.