内存泄漏AlertController / UIImagePickerController

时间:2019-02-12 07:48:50

标签: swift memory-leaks uiimagepickercontroller uialertcontroller

我有一个课,可以从画廊或照相机中选择图片。 我打开一个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)

    }

}

1 个答案:

答案 0 :(得分:0)

UIImagePickerController泄漏是一个已知且非常老的问题:

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

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

self.openGallery(viewController: viewController)

// ...

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