Saving UIImagePickerController images to Core Data without crashing
        Posted  
        
            by Gordon Fontenot
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by Gordon Fontenot
        
        
        
        Published on 2010-06-15T00:09:45Z
        Indexed on 
            2010/06/15
            0:12 UTC
        
        
        Read the original article
        Hit count: 575
        
I have been trying to minimize my memory footprint with UIImagePickerController, but I'm starting to think that the memory problems I am having are resulting from poor memory management, instead of a particular way to handle the UIImagePickerController object.
My workflow is this: The "Edit Image" button is clicked, which presents a UIActionSheet. This action sheet allows you to delete, take a picture, choose from the library, or cancel. If you select Choose from the library or Take Picture, I alloc an instance of UIImagePickerController and present it, followed by a release of UIImagePickerController:
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (actionSheet.tag != 999) {
        UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
        imagePicker.delegate = self;
        BOOL pickImage = nil;
        if (actionSheet.tag == iPhoneWithDelete) {
            switch (buttonIndex) {
                case 0:
                    object.objectImage = nil;
                    pickImage = NO;
                    break;
                case 1:
                    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
                    pickImage = YES;
                    break;
                case 2:
                    imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
                    pickImage = YES;
                    break;
                default:
                    pickImage = NO;
                    break;
            }
        } else if (actionSheet.tag == iPhoneNoDelete) {
            switch (buttonIndex) {
                case 0:
                    imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
                    pickImage = YES;
                    break;
                case 1:
                    imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
                    pickImage = YES;
                    break;
                default:
                    pickImage = NO;
                    break;
            }       
        } else if (actionSheet.tag == iPodWithDelete) {
            switch (buttonIndex) {
                case 0:
                    object.objectImage = nil;
                    pickImage = NO;
                    break;
                case 1:
                    imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
                    pickImage = YES;
                    break;
                default:
                    pickImage = NO;
                    break;
            }
        } else if (actionSheet.tag == iPodNoDelete) {
            switch (buttonIndex) {
                case 0:
                    imagePicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
                    pickImage = YES;
                    break;
                default:
                    pickImage = NO;
                    break;
            }
        }
        if (pickImage) {
            imagePicker.allowsEditing = YES;
            [self presentModalViewController:imagePicker animated:YES];
        } else {
            [self setupImageButton];
            [self setupChooseImageButton];
        }
        [imagePicker release];
    }
}
Once I get a selection back from the UIImagePickerController, I save 2 images, a resized version of the edited image to use for a thumbnail, and a 800x600 version of the original unedited image into a relationship attribute (Transformational, using the same UIImage to PNG transformations found in the Recipes demo code) for display use: (the resize methods are based on the one demoed in this SO post.)
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    [self dismissModalViewControllerAnimated:YES];
    NSManagedObject *oldImage = object.imageFull;
    if (oldImage != nil)
    {
        [object.managedObjectContext deleteObject:oldImage];
    }
    NSManagedObject *image = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:object.managedObjectContext];
    object.imageFull = image;
    UIImage *rawImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    CGSize size = CGSizeMake(800, 600);
    UIImage *fullImage = [UIImageManipulator scaleImage:rawImage toSize:size];
    [image setValue:fullImage forKey:@"imageFull"];
    UIImage *processedImage = [UIImageManipulator scaleImage:[info objectForKey:@"UIImagePickerControllerEditedImage"] toSize:CGSizeMake(75, 75)];
    object.objectImage = processedImage;
    [self setupImageButton];
    [self setupChooseImageButton];
    rawImage = nil;
    fullImage = nil;
    processedImage = nil;
}
When I go through viewDidUnload I am setting self.object = nil, and [object release] during dealloc, but I'm still getting memory warnings after about 10 image changes, with a crash at around 20. It leads me to believe that I am not getting that full image out of memory the correct way. What am I missing here?
And on a second note, does the Camera source use significantly more memory than the Photo Albums source? I tend to get more crashes when using the camera.
© Stack Overflow or respective owner