内存泄漏AlertController / UIImagePickerController

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存泄漏AlertController / UIImagePickerController相关的知识,希望对你有一定的参考价值。

我有一个班级从画廊或相机中挑选一张照片。我打开一个alertController,让你在画廊和相机之间进行选择。它还包含一个代表。如果我从图库中选择一张图片,我发现仪器有内存泄漏。如何改进代码以避免内存泄漏?谢谢!

class ImagePickerManager: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    var imagePicker = UIImagePickerController()
    weak var delegate: DelegatePhotohandler?
    var viewController: UIViewController?

    override init() {
        super.init()
    }

    func pickImage<T:UIViewController>(viewController: T) {
        self.viewController = viewController
        let alertList = UIAlertController(title: NSLocalizedString("Load Picture", comment: "Picture alert Alertcontroller"), message: nil, preferredStyle: .actionSheet)

        let cameraAction = UIAlertAction(title: "Camera", style: .default) {
            UIAlertAction in self.openCamera()
            alertList.dismiss(animated: true, completion: nil)
        }

        let galleryAction = UIAlertAction(title: "Gallery", style: .default) {
            UIAlertAction in self.openGallery()
            alertList.dismiss(animated: true, completion: nil)
        }

        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) {
            UIAlertAction in
            alertList.dismiss(animated: true, completion: nil)
        }

        alertList.addAction(cameraAction)
        alertList.addAction(galleryAction)
        alertList.addAction(cancelAction)

        viewController.present(alertList, animated: true, completion: nil)
    }

    private func openCamera() {

        if(UIImagePickerController .isSourceTypeAvailable(.camera)) {
            imagePicker.sourceType = .camera
            imagePicker.delegate = self
            self.viewController!.present(imagePicker, animated: true, completion: nil)
        } else {
            let warningAlert = UIAlertController(title: "Warning", message: "You do not have a camera", preferredStyle: .alert)
            let cancelAction = UIAlertAction(title: "Okay", style: .cancel) {
                UIAlertAction in
                warningAlert.dismiss(animated: true, completion: nil)
            }
            warningAlert.addAction(cancelAction)
            self.viewController!.present(warningAlert, animated: true, completion: nil)
        }

    }

    private func openGallery() {
        imagePicker.sourceType = .photoLibrary
        imagePicker.delegate = self
        self.viewController!.present(imagePicker, animated: true, completion: nil)
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        picker.dismiss(animated: true, completion: nil)
        guard let image = info[.originalImage] as? UIImage else {
            print("Expected a dictionary containing an image, but was provided the following: (info)")
            return
        }
        delegate?.returnImage(image: image)

    }

}
答案

UIImagePickerController泄漏是一个众所周知的问题:

解决方案是基本上将选择器的实例存储在单例中并在需要时重用它(忽略选择器本身中的小内存泄漏),或者使用没有此问题的第三方图像选择器。

作为旁注,您的代码可以通过删除viewController属性并将其作为参数添加到openCameraopenGallery来改进,如下所示:

self.openGallery(viewController: viewController)

// ...

private func openGallery<T:UIViewController>(viewController: T) {
    imagePicker.sourceType = .photoLibrary
    imagePicker.delegate = self
    viewController.present(imagePicker, animated: true)
}

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

MFC内存泄漏调试

如何防止java中的内存泄漏

记录一次DialogFragment 内存泄漏

常见的内存泄漏原因及解决方法

Android ValueAnimator --内存泄漏

AlertController - 与 UIViewController 冲突