AlertController утечки памяти / UIImagePickerController - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть класс, чтобы выбрать изображение из галереи или камеры.Я открываю 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 голосов
/ 12 февраля 2019

UIImagePickerController утечка - известная и очень старая проблема:

Решение состоит в том, чтобы в основном сохранить экземпляр средства выбора в синглтоне и повторно использовать его при необходимости (игнорируя небольшую утечку памяти в самом устройстве выбора), или использовать стороннее средство выбора изображенийкоторая не имеет этой проблемы.

В качестве sidenote, ваш код может быть улучшен путем удаления свойства viewController и добавления его в качестве аргумента в openCamera и openGallery, например, так:

self.openGallery(viewController: viewController)

// ...

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