Search code examples
iosuiimagepickercontrollerviewcontrollermemory-warning

Always get memory warning when with a UIImagePicker for camera


I am using a UIImagePicker in my viewController,

and there are two kinds of methods in which I always get a memory warning, as well as the very famous "wait_fences: failed to receive reply: 10004003",

but I can't trace to the specific line of code that prompts the warning - it always comes immediately after these methods somewhere I can't debug.

// in myViewController.h

// the first 2 are the methods that I alloc my UIImagePicker,
// here, self.photoPicker is a retained property of UIImagePicker.
- (IBAction)fromAlbumButtonTapped {
    if (self.photoPicker == nil) {
        self.photoPicker = [[[UIImagePickerController alloc] init] autorelease];
        self.photoPicker.delegate = self;
    }
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
        self.photoPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        [self presentModalViewController:self.photoPicker animated:YES];
        return;
    }
}

- (IBAction)fromCameraButtonTapped {
    if (self.photoPicker == nil) {
        self.photoPicker = [[[UIImagePickerController alloc] init] autorelease];
        self.photoPicker.delegate = self;
    }
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        self.photoPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
        [self presentModalViewController:self.photoPicker animated:YES];
        return;
    }
}
// and this is another part that gives me the memory warning - getting a photo.
- (void)imagePickerController:(UIImagePickerController *)picker 
didFinishPickingMediaWithInfo:(NSDictionary *)info {
    self._photo = [info objectForKey:UIImagePickerControllerOriginalImage];
    self.photoView.photoView.image = self._photo;
    [self.photoButton setImage:self._photo forState:UIControlStateNormal];
    [self dismissModalViewControllerAnimated: YES];
}

I've already checked my code and found no potential memory leak as best as I can tell.

I know that dealing with a photo does take some memory, so it is normal to get a memory warning.

But problem is sometimes, my viewController just release something important when the warning comes, such as the some button for going back to parentView controller in a navigation stack.

So I don't want get a memory warning if my buttons or something else important is going to be released too early.

Is there any way to fix it?


Solution

  • Not all memory "loss" is caused by a leak. Use Heapshot.

    Use instruments to check for leaks and memory loss due to retained but not leaked memory. The latter is unused memory that is still pointed to. Use Heapshot in the Allocations instrument on Instruments.

    For HowTo use Heapshot to find memory creap, see: bbum blog

    Basically there method is to run Instruments allocate tool, take a heapshot, run an intuition of your code and another heapshot repeating 3 or 4 times. This will indicate memory that is allocated and not released during the iterations.

    To figure out the results disclose to see the individual allocations.

    If you need to see where retains, releases and autoreleases occur for an object use instruments:

    Run in instruments, in Allocations set "Record reference counts" on on (you have to stop recording to set the option). Cause the picker to run, stop recording, search for there ivar (datePickerView), drill down and you will be able to see where all retains, releases and autoreleases occurred.