Memory leak in iOS when mixing ARC and non-ARC code

Sep 10, 2013 · Follow on Twitter and Mastodon ios

I had an iOS app crash after taking a few photos. The stack trace showed a memory leak, but I had a hard time finding it. Turns out that it was caused by mixing ARC and non-ARC.

When I tried reproducing it, I launched Instruments to see how the app allocates memory. I started taking photos, editing them, but didn’t encounter a memory leak…until I did.

The app has a custom camera view that overlays a crop rectangle and custom views over the image preview. No other camera controls are visible and the result is pretty clean.

The app is all about storing copies of cards in your wallet, so users tend to take photos of their cards placed on a table or a flat horizontal surface. This means that the camera will be facing down, which may give the device a hard time to determine what is up and down.

This can in turn lead to the image being compressed or distorted, so we perform a check to see if the width is smaller than the height. If so, we re-scale the image and voilá, we get an image that is always correct.

But what about that memory leak?

Well, I noticed that the memory leak only occured when you held the camera horizontally, and not always. This lead me to consider what I just described above.

Let’s take a look at the camera delegate code:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
   if (image.size.width < image.size.height) {
      image = [image imageByResizing:CGSizeMake(image.size.height, image.size.width)];
   }
   [picker dismissModalViewControllerAnimated:NO];
   [self openImageEditorWithImage:image];
}

My first guess was that the resize operation caused the memory leak. However, as I looked into this, it turned out that it was the other way around. NOT resizing it caused the leak.

The app was built for iOS 4.3 and didn’t use ARC at first. I added ARC support when it was being released. However, the image editor uses HFImageEditor which does NOT use ARC.

So, as we pass in the original image into the image editor, it can get stuck in memory. This will eventually lead to a crash. If we however set the image variable to something else, the image will be automatically disposed by ARC, and our temp weak image reference will be released as well, as soon as the image editor is done with it.

Discussions & More

Please share any ideas, feedback or comments you may have in the Disqus section below, or by replying on Twitter or Mastodon.

If you found this text interesting, make sure to follow me on Twitter and Mastodon for more content like this, and to be notified when new content is published.

If you like & want to support my work, please consider sponsoring me on GitHub Sponsors.