swift - 内存泄漏 AlertController/UIImagePickerController

标签 swift memory-leaks uiimagepickercontroller uialertcontroller

我有一个类可以从画廊或相机中挑选一张照片。 我打开一个 alertController 并让您在画廊和相机之间进行选择。它还包含一个委托(delegate)。如果我从图库中选择一张图片,我会发现仪器存在内存泄漏。如何改进代码以避免内存泄漏?谢谢!

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)
}

关于swift - 内存泄漏 AlertController/UIImagePickerController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54645147/

相关文章:

swift - 试图理解我得到的这个随机错误//swift

Swift Dictionary 在扩展中使用键访问值

ios - SwiftUI 披露组文本对齐

ios - Objective-c Opengl 内存泄漏

iphone - iPhone 中的内存泄漏

iphone - 如何让 ImagePicker 从底部开始首先显示最新的图像?

macos - Swift - 使用定时器/系统时钟/后台线程每小时在我的应用程序中做一些事情

ruby-on-rails - 递归 ruby​​ 方法中明显的内存泄漏

iphone - 如何获取 UIImagePickerControllerReferenceURL 相机

ios - UIImage 没有从一个 ViewController 传递到另一个