Tocropviewcontroller: Mögliches Speicherleck?

Erstellt am 8. März 2018  ·  4Kommentare  ·  Quelle: TimOliver/TOCropViewController

Ich verwende CropViewController für Swift und habe es gestern erst installiert, damit mein Pod auf dem neuesten Stand ist. Ich mag es wirklich, guter Job, aber ich denke, es ist ein möglicher Speicherverlust aufgetreten.

Ich erstelle einfach einen neuen UIViewController und präsentiere ihn modal. Ich habe UIImageView auf diesem Controller und es hat eine Tap-Erkennung. Ich verwende UIImagePickerController und präsentiere das CropViewController-Objekt, wenn die Medienauswahl abgeschlossen ist;

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

Nach dem Beschneiden und Schließen dieses UIViewControllers wurde deinit nie aufgerufen. Wenn ich imagePickerController Delegate-Methode wie folgt ändere;

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

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

dann, wenn ich entlassen werde, ruft deinit an. Ich setze hier keine speziellen Elemente, nur UIViewController, UIImageView und UIImagePickerController. Habe ich etwas falsch eingestellt oder ist das ein Speicherleck?

- BEARBEITEN -

Wenn ich deinit in deiner CropViewController.swift Klasse anrufe, wird es auch nicht aufgerufen.

bug

Hilfreichster Kommentar

okay.. ich habe es mit folgendem behoben
1- Ich habe den Delegierten schwach gemacht, weil Delegierte immer schwach sein sollten
2- Ich habe die Selbstaufrufe innerhalb der Handler gemacht, um [schwaches Selbst] zu sein

In Ihrer CropViewController.swift sehen Sie die onDid... Callbacks.

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

Alle 4 Kommentare

Hallo @kcankaynak!

Oh-oh. Du hast recht. Das riecht sicherlich nach einem Speicherleck. Muss ich bei Gelegenheit mal in der Beispiel-App ausprobieren. Danke für die Information!

Ich habe das gleiche Problem, es gibt einen Retain-Zyklus, der dazu führt, dass mein UIViewController (der, der Ihren Crop-VC präsentiert) nicht freigegeben wird, er ruft die deinit-Methode nicht auf, wie @kcankaynak erwähnt. Ich dachte, es wäre Ihr CroppingVC-Delegierter, der nicht SCHWACH ist, weil Sie Ihre Delegierteneigenschaft als

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

Also dachte ich.. vielleicht

öffentlicher schwacher var-Delegierter: CropViewControllerDelegate? {
didSet { self.setUpDelegateHandlers() }
}

wird es beheben... aber es hat nicht :(

okay.. ich habe es mit folgendem behoben
1- Ich habe den Delegierten schwach gemacht, weil Delegierte immer schwach sein sollten
2- Ich habe die Selbstaufrufe innerhalb der Handler gemacht, um [schwaches Selbst] zu sein

In Ihrer CropViewController.swift sehen Sie die onDid... Callbacks.

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

Dies wurde in einer anderen PR zusammengeführt. Dank dafür!

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

TimOliver picture TimOliver  ·  12Kommentare

TimOliver picture TimOliver  ·  4Kommentare

Srosman picture Srosman  ·  3Kommentare

ClaesClaes picture ClaesClaes  ·  6Kommentare

trr-amsiq picture trr-amsiq  ·  10Kommentare