1

I'm getting this error "[Not A Type release]: message sent to deallocated instance" on the last line of code "CGImageRelease(imageToSave);". Please explain why and what I need to use to fix it. I'm using ARC, but I don't think that applies to CG objects. I've updated the code with the suggested answers after testing that they work.

CGImageRef imageToSave;
UIImage *uiImageToSave = [[UIImage alloc] init];
if (sender == nil) {
    imageToSave = [originalImage CGImage];
} else {
    uiImageToSave = [self addTitleBlock:annotatedImage];
    imageToSave = [uiImageToSave CGImage];
}
[library writeImageToSavedPhotosAlbum:imageToSave metadata:imageMetadata completionBlock:^(NSURL *assetURL,NSError *error){
    [saveAlertView dismissWithClickedButtonIndex:0 animated:YES]; 
    [activityIndicator stopAnimating];
    [activityIndicator removeFromSuperview];
    if(error == nil) {
        if (sender != nil) {
            [self setToolbarItems:viewingToolbarItems animated:YES];
            [UIView beginAnimations:@"savePhoto" context:NULL]; 
            [UIView setAnimationTransition:PHOTO_SAVE forView:pictureView cache:YES]; 
            [UIView setAnimationDuration:0.5f];
            [UIView setAnimationDelay:0.0f];
            [UIView setAnimationPosition:CGPointMake(45, 430)];
            [splashScreen setHidden:NO];
            [imageView setHidden:YES];
            [sampleImageView setHidden:YES];
            [colorImageView setHidden:YES];
            [UIView commitAnimations];
        } else {
            [saveButton setEnabled:YES];
            [cancelButton setEnabled:YES];
        }
    } else {
          if (sender != nil) {
             saveAlertView=[[UIAlertView alloc] initWithTitle:nil message:@"Image Save Failed!" delegate:self cancelButtonTitle:@"Continue" otherButtonTitles:nil];
         } else {
             saveAlertView=[[UIAlertView alloc] initWithTitle:nil message:@"Original Image Save Failed!" delegate:self cancelButtonTitle:@"Continue" otherButtonTitles:nil];
         }
        [saveAlertView show];
        [saveButton setEnabled:YES];
        [cancelButton setEnabled:YES];
    }
    // CGImageRelease(imageToSave);
}];
T.J.
  • 3,942
  • 2
  • 32
  • 40
  • 2
    You haven't created the image with CGImage*Create* or used CGImageRetain so, you don't have to release it. Just remove the CGImageRelease instruction. You can read more about when you are responsible of releasing CGImage at https://developer.apple.com/library/ios/#documentation/graphicsimaging/reference/CGImage/Reference/reference.html – AmineG Mar 05 '12 at 22:37

1 Answers1

4

Even worse than what someone0 is telling you:

I would say as you defined your uiImageToSave in the else block, the reference you created with imageToSave is not valid outside of the else block - so any use of imageToSave in your code is just working by accident, as long as the memory is not overwritten yet.

And as said, the [UIImage CGImage] call only gives you a reference to the image data, it does not make a copy or retain it - so you may not release it yourself, it is released automatically when the UIImage ceases to exist - which in your case is just one line after you make the reference.

UPDATE:

The code in the original posting is adjusted - the uiImageToSave is now defined in the right place (just if anyone wonders about my comment which is now not really fitting the original posting anymore :-).

TheEye
  • 9,280
  • 2
  • 42
  • 58
  • That makes sense and the changes work. I've updated the code. Thanks, and also thank you to @someone0. – T.J. Mar 06 '12 at 04:27