Reputation: 5132
Just learning how to allocate tasks among threads, or dispatch asynchronously. I understand that any operation that "touches" a view must be done on the main thread. What about: UIImageWriteToSavedPhotosAlbum
? I would assume this could be done on a background thread, but am I mistaken?
Also, if it should be done on a background thread, is there a difference between these two calls below, as one saves a UIImage and the other saves a UIImage from a view?
UIImageWriteToSavedPhotosAlbum(_someUIImage ,nil,nil,nil);
UIImageWriteToSavedPhotosAlbum(_imageView.image ,nil,nil,nil);
By the way I am using this setup to run an HUD in the main thread and to tasks in the background, that 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];
});
});
Upvotes: 4
Views: 4108
Reputation: 5132
Here is my latest code after reading the answers, if anyone cares to know, or to 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];
}
}
The myPerformBlock is from the following link https://gist.github.com/955123
Upvotes: 3
Reputation: 386068
UIKit classes are documented to be usable from the main thread only, except where documented otherwise. (For example, UIFont
is documented to be thread-safe.)
There's no explicit blanket statement about the thread safety of UIKit functions (as distinct from classes), so it's not safe to assume they generally thread-safe. The fact that some UIKit functions, like UIGraphicsBeginImageContext
, are explicitly documented to be thread-safe, implies that UIKit functions are not generally thread-safe.
Since UIImageWriteToSavedPhotosAlbum
can send an asynchronous completion message, you should just call it on the main thread and use its completion support to perform your [HUD_code dismiss]
.
Upvotes: 5
Reputation:
I would assume this could be done on a background thread, but am I mistaken?
Honestly, I would assume it too, since this has absolutely nothing to do with updating the UI, it's just some file operation. However, Apple's documentation says that every call to UIKit needs to be performed on the main thread (Except where something else is explicitly stated). This function is no exception, you have to call it on the main thread.
By the way, this function is asynchronous itself. It will notify the callback object/selector supplied as its 2nd and 3rd arguments when the image is saved, and thus it doesn't block the UI.
Upvotes: 1