Search code examples
iphonexcodememory-managementcgimage

CGImageRelease: [Not A Type release]: message sent to deallocated instance


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);
}];

Solution

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