Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIImagePickerController leaking on iOS 11

I've configured my UIImagePickerController for taking an image and for recording a video both independently. The UIImagePickerController is directly called from an @IBAction (by a UIButton). I receive both UIImage and URL from the video in the imagePickerController delegate method and print them for testing purposes.

After waiting a little while (10 seconds) I select Xcode's "View Memory Graph History" in which I can see that in both testing cases I have memory leaks and also cyclic references. I can also see those memory leaks in Instruments if someone thinks it's an Xcode bug.

This happens when I record a video:

memory leaks video

And this happens when I take a picture:

memory leaks photo

You can reproduce this results with this code on a iOS 11.2 device (I don't think simulators would work):

import UIKit

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    @IBAction func takePhoto(_ sender: Any) {

        let picker = UIImagePickerController()
        picker.delegate = self
        picker.sourceType = .camera
        picker.allowsEditing = false

        self.present(picker, animated: true, completion: nil)
    }

    @IBAction func recordVideo(_ sender: Any) {

        let picker = UIImagePickerController()
        picker.delegate = self
        picker.sourceType = .camera
        picker.allowsEditing = false
        picker.mediaTypes = ["public.movie"]
        picker.videoQuality = .typeHigh

        self.present(picker, animated: true, completion: nil)
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: Any]) {

        picker.dismiss(animated: true, completion: nil)

        if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
            print(image.size)
        }

        if let video = info[UIImagePickerControllerMediaURL] as? URL {
            print(video.path)
        }
    }

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }

}

Now my question is: Can I fix those with some workaround or am I doing something wrong in my code, is this a bug by Apple, should I just ignore it?

Edit: If anyone wants to take a look at the whole project: https://github.com/ph1ps/UIImagePickerLeak

like image 879
ph1psG Avatar asked Feb 05 '23 02:02

ph1psG


1 Answers

I would say just ignore the "leaks" you are seeing. While, I don't have any code to back this up, I do have some experience finding and fixing memory leaks on-the-job. In my experience, when you're finding leaks, you look for smoking guns. So for the memory graph history, I would suspect that there might be a memory leak if there were hundreds or thousands of instances of some type leaked. This goes for mobile apps as well. From what I can see from your screenshots, you're leaking at most 1k, which (assuming there even is a leak) is pretty trivial. As such, you really don't appear to have a leak.

like image 88
entpnerd Avatar answered Feb 10 '23 23:02

entpnerd