Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Instruments to trace memory leak Xcode5 and iOS7

I developed my first app and still learning. Just updated Xcode 5 yesterday and my iPhone 5 is running iOS 7.1. I am now working on understanding the Instruments tool to analyze my app. I am using the Leak profile in Instruments and have come across a retain cycle and leak which I can't figure out. Appreciate any help I can get to understand a) how to pinpoint the bug and b) what I did wrong and how to avoid it in the future.

In my app, I am using the camera to take a pic. While the camera is up, I tapped on the screen to focus and that is when I noticed the leak pop up in Instruments. Looks like there is a retain cycle not in my code (if I understand correctly) and a root leak in my code which I don't understand.

I am using ARC, so I should not have to release "picker" in the part of my code that Instruments is pointing me to (part 2 below, with code).

CALayer Retain Cycle

  1. What can I do about the retain cycle. It is not in my code, but am I still the cause of it? Does it stem from the "root leak?" If I am NOT responsible for it, what's should I do about it?

Root Leak

  1. My only code in this stack trace does not help me understand where the leak is coming from. The line is Instruments points me to in my code is [picker dismissViewControllerAnimated:YES completion:nil]; in my imagePickerController:didFinishPickingMediaWithInfo: method. I am pasting the code below.
 - (void)imagePickerController:(UIImagePickerController *)picker
    didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    UIImage *pickerImage = [info objectForKey:
                            UIImagePickerControllerOriginalImage];

    _imageView.image = pickerImage;

    [picker dismissViewControllerAnimated:YES completion:nil]; // <--- mem-leak
}

EDIT - Code where I create my UIImagePickerController.

- (IBAction)snapPicture:(id)sender
{
    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];

    // If the camera button was tapped AND we have a camera, use it...
    if ((sender == _cameraButton) && [UIImagePickerController
         isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
    {
        [imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
    } else {
        [imagePicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
    }

    imagePicker.delegate = self;

    // bring up the image picker view
    [self presentViewController:imagePicker animated:YES completion:nil];
}
like image 618
knarf Avatar asked Mar 20 '23 02:03

knarf


1 Answers

Here's my theory: what you've encountered is evidently a bug (or flaw) in Apple's own code, and all you can do is laugh maniacally and forget about it.

To test my theory, I ran my own code, written totally separately and at a different time. It does almost the same thing your code does: it lets the user take a picture, and puts the image into the interface. Here's my code:

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch17p702takeAPicture/ch30p962takeAPicture/ViewController.m

I ran my code under Instruments with the Leaks instrument, and guess what? I saw the same issues you did.

enter image description here

Naturally, I then started searching on Stack Overflow, and all of this turns out to be old ground. For example:

UIImagePickerController memory leak on iOS5

Even Apple's own sample code, called PhotoPicker (or Using UIImagePickerController to Select Pictures and Take Photos) has the same leak.

like image 160
matt Avatar answered Mar 31 '23 22:03

matt