Search code examples
iosalassetslibrary

Saving photo to library more than once using ALAssetsLibrary causes crash


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?


Solution

  • 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.