I have a method that saves a photo to the user's photo library. This code works perfectly the first time you save the photo to the library, but if you try to save it a second time the app will crash.
Here is the method:
- (void)saveToLibray
{
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Request to save the image to camera roll
[library writeImageToSavedPhotosAlbum:[self.image CGImage] orientation:(ALAssetOrientation)[self.image imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){
if (error) {
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:nil message:@"Could not save photo to your library. Please enable Halfsies in Settings > Privacy > Photos." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
CGImageRelease([self.image CGImage]);
} else if (!error) {
UIAlertView *librarySaveSuccessAlertView = [[UIAlertView alloc]initWithTitle:@"Success!" message:@"Your finished halfsie was successfully saved to your photo library!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[librarySaveSuccessAlertView show];
CGImageRelease([self.image CGImage]);
}
}];
}
I have made sure to release the CGImage
and I am also waiting for the librarySaveSuccessAlertView
to show on the screen, clicking it's OK button (cancelButtonTitle
), and then I try and save a second time.
On the second time, the app always crashes.
Is this happening because the library can detect duplicate photos, or is it something else?
EDIT: Crash details
On the line that is highlighted green after the app crashes, it says:
Thread 1: EXC_BAD_ACCESS(code=1, address=0x657471ef)
EDIT 2: Ok, so I realize now that it is most likely because I am trying to send a message to a released object. I'm confused on how I should handle this. Even though I'm releasing the CGImage
data of self.image
, I should still be able to access it again on the second save correct?
As you already suspect (well done), the problem is this line:
CGImageRelease([self.image CGImage])
You are required to release a CG-type object if and only if you called a Create
or Copy
method to obtain it. For example, you might have obtained this CGImage by calling the function CGImageCreate()
. You didn't do anything like that here, so this is not your object to release. So simply cut those lines, stop doing incorrect memory management, and all will be well.