Tocropviewcontroller: Возможна утечка памяти?

Созданный на 8 мар. 2018  ·  4Комментарии  ·  Источник: TimOliver/TOCropViewController

Я использую CropViewController для быстрого и только что установил вчера, так что мой модуль обновлен. Мне это очень нравится, молодец, но я думаю, что произошла утечка памяти.

Я просто создаю новый UIViewController и представляю его модально. У меня есть UIImageView на этом контроллере, и у него есть распознаватель касаний. Я использую UIImagePickerController и представляю объект CropViewController, когда выбор мультимедиа заканчивается, например:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

        if let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
            let cropVC = CropViewController(croppingStyle: .circular, image: selectedImage)
            cropVC.delegate = self
            picker.present(cropVC, animated: false, completion: nil)
        } 
    }

После завершения обрезки и отклонения этого UIViewController deinit никогда не вызывается. Если я меняю метод делегата imagePickerController следующим образом;

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

        if let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
            self.imageView.image = selectedImage
        } 
    }

тогда, если меня увольняют, deinit звонит. Я не устанавливаю никаких специальных элементов, здесь только UIViewController, UIImageView и UIImagePickerController. Я что-то неправильно настроил или это утечка памяти?

- РЕДАКТИРОВАТЬ -

Когда я вызываю deinit в вашем классе CropViewController.swift , он не вызывается.

Самый полезный комментарий

хорошо .. Я исправил это следующим
1- Я сделал делегата слабым, потому что делегаты всегда должны быть слабыми
2- Я сделал самовызовы внутри обработчиков, чтобы быть [слабым я]

В вашем CropViewController.swift просмотрите обратные вызовы onDid ...

fileprivate func setUpDelegateHandlers() {
        guard let delegate = self.delegate else {
            onDidCropToRect = nil
            onDidCropImageToRect = nil
            onDidCropToCircleImage = nil
            onDidFinishCancelled = nil
            return
        }

        if delegate.responds(to: #selector(CropViewControllerDelegate.cropViewController(_:didCropImageToRect:angle:))) {
            self.onDidCropImageToRect = {[weak self] rect, angle in
                delegate.cropViewController!((self)!, didCropImageToRect: rect, angle: angle)
            }
        }

        if delegate.responds(to: #selector(CropViewControllerDelegate.cropViewController(_:didCropToImage:withRect:angle:))) {
            self.onDidCropToRect = {[weak self] image, rect, angle in
                delegate.cropViewController!((self)!, didCropToImage: image, withRect: rect, angle: angle)
            }
        }

        if delegate.responds(to: #selector(CropViewControllerDelegate.cropViewController(_:didCropToCircularImage:withRect:angle:))) {
            self.onDidCropToCircleImage = {[weak self] image, rect, angle in
                delegate.cropViewController!((self)!, didCropToCircularImage: image, withRect: rect, angle: angle)
            }
        }

        if delegate.responds(to: #selector(CropViewControllerDelegate.cropViewController(_:didFinishCancelled:))) {
            self.onDidFinishCancelled = { [weak self] finished in
                delegate.cropViewController!((self)!, didFinishCancelled: finished)
            }
        }
    }

Все 4 Комментарий

Привет @kcankaynak!

Ой-ой. Ты прав. Это определенно пахнет утечкой памяти. Мне нужно будет попробовать это в образце приложения, когда у меня будет возможность. Спасибо, что дали мне знать!

У меня такая же проблема, существует цикл сохранения, из-за которого мой UIViewController (тот, который представляет ваш VC урожая) не выпускается, он не вызывает метод deinit, как упоминалось в @kcankaynak . Я думал, что ваш делегат croppingVC не СЛАБЫЙ, потому что у вас было свойство делегата как

public var delegate: CropViewControllerDelegate? {
        didSet { self.setUpDelegateHandlers() }
    }

так я подумал .. может быть

публичный слабый делегат var: CropViewControllerDelegate? {
didSet {self.setUpDelegateHandlers ()}
}

исправлю ... но этого не произошло :(

хорошо .. Я исправил это следующим
1- Я сделал делегата слабым, потому что делегаты всегда должны быть слабыми
2- Я сделал самовызовы внутри обработчиков, чтобы быть [слабым я]

В вашем CropViewController.swift просмотрите обратные вызовы onDid ...

fileprivate func setUpDelegateHandlers() {
        guard let delegate = self.delegate else {
            onDidCropToRect = nil
            onDidCropImageToRect = nil
            onDidCropToCircleImage = nil
            onDidFinishCancelled = nil
            return
        }

        if delegate.responds(to: #selector(CropViewControllerDelegate.cropViewController(_:didCropImageToRect:angle:))) {
            self.onDidCropImageToRect = {[weak self] rect, angle in
                delegate.cropViewController!((self)!, didCropImageToRect: rect, angle: angle)
            }
        }

        if delegate.responds(to: #selector(CropViewControllerDelegate.cropViewController(_:didCropToImage:withRect:angle:))) {
            self.onDidCropToRect = {[weak self] image, rect, angle in
                delegate.cropViewController!((self)!, didCropToImage: image, withRect: rect, angle: angle)
            }
        }

        if delegate.responds(to: #selector(CropViewControllerDelegate.cropViewController(_:didCropToCircularImage:withRect:angle:))) {
            self.onDidCropToCircleImage = {[weak self] image, rect, angle in
                delegate.cropViewController!((self)!, didCropToCircularImage: image, withRect: rect, angle: angle)
            }
        }

        if delegate.responds(to: #selector(CropViewControllerDelegate.cropViewController(_:didFinishCancelled:))) {
            self.onDidFinishCancelled = { [weak self] finished in
                delegate.cropViewController!((self)!, didFinishCancelled: finished)
            }
        }
    }

Это было объединено в другой пиар. Спасибо за это!

Была ли эта страница полезной?
0 / 5 - 0 рейтинги