IOS: dispatch_async and UIImageWriteToSavedPhotosAlbum

Just learn how to distribute tasks between threads or send asynchronously. I understand that any operation that β€œtouches” a view must be performed in the main thread. What about: UIImageWriteToSavedPhotosAlbum ? I would suggest that this can be done in the background thread, but am I mistaken?

Also, if you need to do this in the background thread, is there a difference between the two calls below since one saves the UIImage and the other saves the UIImage from the view?

 UIImageWriteToSavedPhotosAlbum(_someUIImage ,nil,nil,nil); UIImageWriteToSavedPhotosAlbum(_imageView.image ,nil,nil,nil); 

By the way, I use this setting to start the HUD in the main thread and for tasks in the background, this is my intention.

 [HUD_code showMessage:@"saving image"]; dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(concurrentQueue, ^{ UIImageWriteToSavedPhotosAlbum(someUIImage ,nil,nil,nil); dispatch_async(dispatch_get_main_queue(), ^{ [HUD_code dismiss]; }); }); 
+4
source share
3 answers

UIKit classes are documented for use only from the main thread , unless otherwise documented. (For example, UIFont documented as thread safe .)

There is no explicit statement about the safety of UIKit function threads (as opposed to classes), so it is unsafe to assume that they are generally thread safe. The fact that some UIKit functions, such as UIGraphicsBeginImageContext , are explicitly documented as thread-safe, implies that UIKit functions are not generally thread-safe.

Since UIImageWriteToSavedPhotosAlbum can send an asynchronous completion message, you just need to call it in the main thread and use its completion support to execute [HUD_code dismiss] .

+5
source

Here is my last code after reading the answers, if someone wants to know or comment (appreciated).

 -(void)saveToLibrary { if (_imageView.image != NULL) { messageHUD = @"Saving Image..."; [SVProgressHUD showWithStatus:messageHUD]; UIImageWriteToSavedPhotosAlbum(_imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); } } - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo { UIAlertView *alert; // Unable to save the image if (error) { alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Unable to save image to Photo Album." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil]; }else {// All is well messageHUD = @"Success!\nImage Saved."; [SVProgressHUD showSuccessWithStatus:messageHUD]; [self myPerformBlock:^{[SVProgressHUD dismiss];} afterDelay:0.5]; } } 

MyPerformBlock has the following link https://gist.github.com/955123

+3
source

I would suggest that this can be done in the background thread, but am I mistaken?

Honestly, I would also accept this, since it has nothing to do with updating the user interface, it is just a file operation. However, Apple's documentation says that every UIKit call should be made in the main thread (unless explicitly stated otherwise). This function is no exception; it must be called in the main thread.

By the way, this function itself is asynchronous. It will notify the callback object / selector provided as its second and third arguments when the image is saved, and therefore it does not block the user interface.

+1
source

All Articles