我已经配置了我的UIImagePickerController
来拍摄图像和独立录制视频。 UIImagePickerController
直接从@IBAction
(由UIButton
)调用。我从UIImage
委托方法的视频中收到URL
和imagePickerController
,并将其打印用于测试目的。
稍等片刻(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
我会说只是忽略你所看到的“漏洞”。虽然,我没有任何代码支持这一点,但我确实有一些在工作中查找和修复内存泄漏的经验。根据我的经验,当你发现泄漏时,你会寻找吸烟枪。因此,对于内存图历史记录,如果有数百或数千个某些类型的实例泄露,我会怀疑可能存在内存泄漏。这适用于移动应用程序。从我从你的截图中看到的,你最多泄漏1k,这(假设甚至有泄漏)是非常微不足道的。因此,您似乎确实没有泄漏。
我添加了一些代码来证明没有内存泄漏。您可以通过我的代码或内存图来判断它。我已经提出了拉取请求。
我看到有关是否有泄漏的各种相互矛盾的信息。
首先......有,它的不一致是令人沮丧的人群。
我在使用UIImagePickerController时完全看到了保留。如果遇到问题,有一些问题。我有一个用户配置文件编辑器,有两个地方可以拍摄/选择一个图像(一个用于人,一个用于他的车辆)。当我对两者使用完全相同的代码时,一个发布就好了,我的profileEditViewController就可以了。当我使用另一个,甚至取消选择图像时,它不会释放,我的控制器永远不会取消。完全相同的代码。这两个地方都是100%。
我认为它归结为委托保留,但我尝试不设置委托(因此使其基本无用),并且相同的结果显而易见。刚刚启动第二个UIImagePickerController导致了一个保留锁定,甚至为第二个变量声明了另一个变量。我可以通过简单地从不启动第二个选择器来让我的控制器去除,但是内存不会掉落。
它保留,即使与我的控制器断开连接。当Apple的最严格的例子出现在生产代码中的字母时,这有点愚蠢:(