UIImagePickerController Memory Leak

2020-01-28 08:17发布

问题:

I am seeing a huge memory leak when using UIImagePickerController in my iPhone app. I am using standard code from the apple documents to implement the control:

    UIImagePickerController* imagePickerController = [[UIImagePickerController alloc] init];
    imagePickerController.delegate = self;
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {

        switch (buttonIndex) {
            case 0:
                imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
                [self presentModalViewController:imagePickerController animated:YES];
                break;
            case 1:
                imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
                [self presentModalViewController:imagePickerController animated:YES];
                break;
            default:
                break;
        }
    }

And for the cancel:

-(void) imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [[picker parentViewController] dismissModalViewControllerAnimated: YES];
    [picker release];
}

The didFinishPickingMediaWithInfo callback is just as stanard, although I do not even have to pick anything to cause the leak.

Here is what I see in instruments when all I do is open the UIImagePickerController, pick photo library, and press cancel, repeatedly. As you can see the memory keeps growing, and eventually this causes my iPhone app to slow down tremendously.

As you can see I opened the image picker 24 times, and each time it malloc'd 128kb which was never released. Basically 3mb out of my total 6mb is never released.

This memory stays leaked no matter what I do. Even after navigating away from the current controller, is remains the same. I have also implemented the picker control as a singleton with the same results.

Here is what I see when I drill down into those two lines:

Any help here would be greatly appreciated! Again, I do not even have to choose an image. All I do is present the controller, and press cancel.

Update 1

I downloaded and ran apple's example of using the UIIMagePickerController and I see the same leak happening there when running instruments (both in simulator and on the phone).

http://developer.apple.com/library/ios/#samplecode/PhotoPicker/Introduction/Intro.html%23//apple_ref/doc/uid/DTS40010196

All you have to do is hit the photo library button and hit cancel over and over, you'll see the memory keep growing.

Any ideas?

Update 2

I only see this problem when viewing the photo library. I can choose take photo, and open and close that one over and over, without a leak.

回答1:

It's a bug in the SDK. File a report with Apple. I have the samme isue. It is also documented here: http://www.cocoabuilder.com/archive/cocoa/285293-iphone-memory-leak-can-explain.html and that was over a year ago and still no fix.



回答2:

A few of our apps reuse the same UIImagePickerController due to a leak in 2.x (it makes me feel old...). I was under the impression that the leak was fixed, but I could be wrong.

It's a slightly horrible workaround, but sometimes that's the best you can do.



回答3:

Try setting the UIImagePickerController.delegate to nil before releasing.

-(void) imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [[picker parentViewController] dismissModalViewControllerAnimated: YES];
    picker.delegate = nil;
    [picker release];
}


回答4:

The "Mark Heap" button in Instruments has been, for me, the absolute best way of tracking down these sorts of issues.

This is an OK article on how to use it: http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/

But it will tell you, for sure, which objects are surviving longer than you expect... and, ultimately, what the source of the issue is.

You can also see a complete retain/release trace for each individual object which survived - allowing you to pinpoint where your problem is.

EDIT: I use a UIImagePickerControllers as well, and I can promise it doesn't leak (at lesat for me) the way you're suggesting - so, whatever is going on, it's almost surely fixable.



回答5:

I used UIImagePickerController and after 40 capture images my application received a DidMemoryWarning message and stop, hidden all my views.

In my application I create 40 objects of

UIImagePickerController( new UIImagePickerController() )

To work correctly I create a unique instance shared to all application and with this all work correctly.

I supusose that control lost memory too, but only one time. My application can capture images from camera correctly:

private static UIImagePickerController picker = new UIImagePickerController();