UIImagePickerController 在 iOS 11 上泄漏

Posted

技术标签:

【中文标题】UIImagePickerController 在 iOS 11 上泄漏【英文标题】:UIImagePickerController leaking on iOS 11 【发布时间】:2018-07-08 10:41:01 【问题描述】:

我已将UIImagePickerController 配置为独立拍摄图像和录制视频。 UIImagePickerController 直接从 @IBAction 调用(由 UIButton 调用)。我在imagePickerController委托方法中从视频中收到UIImageURL,并将它们打印出来用于测试目的。

稍等片刻(10 秒)后,我选择 Xcode 的“查看内存图历史记录”,在其中我可以看到在两个测试案例中我都有内存泄漏和循环引用。如果有人认为这是 Xcode 错误,我还可以在 Instruments 中看到这些内存泄漏。

当我录制视频时会发生这种情况:

当我拍照时会发生这种情况:

您可以在 ios 11.2 设备上使用此代码重现此结果(我认为模拟器行不通):

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)
    


现在我的问题是:我可以通过一些变通方法修复这些问题,还是我在代码中做错了什么,这是 Apple 的错误,我应该忽略它吗?

编辑:如果有人想看看整个项目:https://github.com/ph1ps/UIImagePickerLeak

【问题讨论】:

我没有这个问题,但我也没有在视频中使用UIImagePIckerController。但是让我印象深刻的是这条线:let picker = UIImagePickerController() 这是inside recordVideo(sender:Any)。首先,要创建多少个控制器实例?其次,如果您将事情从 Any 更改为 UIPickerViewController - Xcode 将 IMO 默认设置为非常混乱的方式 - 这有帮助吗?最后,您是否还有其他资源可以将此控制器用于视频 @dfd IBActionss 只被调用一次,它仍然会发生。正如我所说,拍照时也会发生这种情况。我将尝试在函数之外创建选择器。 @dfd 在IBAction 之外定义选择器不会改变任何东西:( 如果拍摄静止图像时发生这种情况,我猜你还没有给我们导致问题的代码。我在三个应用程序中使用UIImagePickerController 没有问题。我的大部分代码都是相似的......除了更全局地实例化选择器,并检查设备上的摄像头。后者不应该有任何区别。如果我的想法不起作用,也许您需要快速/小步退后...创建一个项目(不是框架),添加东西(在您的框架上测试下一个),直到找到原因内存泄漏。祝你好运。 @dfd 我发誓这就是它的全部代码。我在 Github 上发布了我的整个项目:github.com/ph1ps/UIImagePickerLeak。也许你可以自己看看并测试一下。 【参考方案1】:

我添加了一些代码来证明没有内存泄漏。您可以通过我的代码或内存图来判断它。我已经提出了拉取请求。

https://github.com/Andy1984/UIImagePickerLeak

【讨论】:

UIImagePickerController 没有泄漏,但有些对象以某种方式与之连接。我以为你可以将一些代表设置为零,他们就会消失。但仍然......这是截图imgur.com/a/scEDu【参考方案2】:

我想说忽略您所看到的“泄漏”。虽然,我没有任何代码来支持这一点,但我确实有一些在工作中发现和修复内存泄漏的经验。根据我的经验,当你发现泄漏时,你会寻找确凿的证据。因此,对于内存图历史,我怀疑如果有成百上千个某种类型的实例泄漏,则可能存在内存泄漏。这也适用于移动应用程序。从我从您的屏幕截图中可以看出,您最多泄漏 1k,这(假设甚至存在泄漏)非常微不足道。因此,您似乎真的没有泄漏。

【讨论】:

我想我必须坚持这个解决方案。我无法修复这个泄漏,这让我很恼火。无论如何,谢谢。【参考方案3】:

我看到关于是否存在泄漏的各种相互矛盾的信息。

首先...有,它的不一致让人们感到沮丧。

我在使用 UIImagePickerController 时完全看到了保留。 IS 如果有问题的话。我有一个用户配置文件编辑器,它有两个地方可以拍摄/选择图像(一个用于人,一个用于他的车辆)。当我对两者都使用完全相同的代码时,一个版本就好了,我的 profileEditViewController deinits 就好了。当我使用另一个时,即使取消选择图像,它也不会释放,并且我的控制器永远不会取消。完全相同的代码。两个地方100%。

我认为这归结为委托保留,但我尝试不设置委托(因此使其基本上无用),同样的结果显而易见。仅仅启动第二个 UIImagePickerController 就导致了一个保留锁,甚至为第二个声明了一个完整的其他变量。我可以通过简单地从不启动第二个选择器来让我的控制器取消初始化,但是内存不会下降。

即使与我的控制器断开连接,它也会保留。遵循 Apple 对生产代码中最严格的示例的情况,这有点愚蠢:(

【讨论】:

我刚刚创建了一个 ImagePickerContoller 单例,没有对我的代码做任何其他事情。使用 UIImagePickerController 的一个实例,我拍摄数十张照片的内存使用量只是原来的一小部分。除了没有为我需要拍摄的每张照片创建新的 UIImagePIckerController 之外,我没有进行其他更改。这种颠覆别人说没有泄漏。正如你所说,肯定存在某种内存问题!

以上是关于UIImagePickerController 在 iOS 11 上泄漏的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 7 中呈现 UIImagePickerController 的问题

如何在 iPad 上关闭 UIImagePickerController

仅在横向 UIImagePickerController 中显示CameraControls

UIImagePickerController 在 iOS 11 上泄漏

UIImagePickerController 呈现在视图中

在 iOS 7 上显示 UIImagePickerController 会导致崩溃