Tocropviewcontroller: メモリリークの可能性はありますか?

作成日 2018年03月08日  ·  4コメント  ·  ソース: TimOliver/TOCropViewController

私はCropViewControllerをswiftに使用していて、昨日インストールしたばかりなので、ポッドは最新です。 私はそれが本当に好きです、良い仕事の人ですが、メモリリークが発生した可能性があると思います。

新しい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のみを設定します。 設定に問題がありますか、それともメモリリークですか?

-編集-

CropViewController.swiftクラスでdeinitを呼び出すと、どちらも呼び出されません。

bug

最も参考になるコメント

大丈夫..私はそれを次のように修正しました
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を提示するもの)が解放されません。 @ kcankaynakが述べたようにdeinitメソッドを呼び出しません。 デリゲートプロパティが次のようになっているため、cropingVCデリゲートが弱くないと思いました。

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

だから私は思った..多分

パブリックウィーク変数デリゲート: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)
            }
        }
    }

これは別のPRに統合されました。 それをありがとう!

このページは役に立ちましたか?
0 / 5 - 0 評価