読者です 読者をやめる 読者になる 読者になる

【swift】ViewControllerのdeinitが呼ばれなかったときの対応メモ

swift ios iPhoneアプリ開発

はじめに

pcにiPhoneをつないでxcodeでcpuやらメモリの使用量やらをリアルタイムに見ることができるのでそれをしました。
画面をひらくたびにメモリ使用量が増えるはわかるんですけど、UiNavigationControllerの戻るとかやってもメモリが減らなくておかしいなぁと思って調べていたら今回の問題がわかりました

結論からいうとdelegateしてる箇所が原因でした

問題のコード

ViewControllerからアプリ共通で使用しているカスタムUiViewを使っていたのですが、どうやらそこが問題でした

ViewController.swift

class ViewController: UIViewController, CustomViewDelegate
{
    override func viewDidLoad()
    {
        super.viewDidLoad()

        let customView: CustomView = CustomView()
        customView.delegate = self
    }

    deinit
    {
        print("deinit is called by ViewContoller.") // ★これがいつまでたっても呼ばれない
    }

    func delegateMethod()
    {
        //  なんらかの処理
    }
}

CustomView.swift

class CustomView: UIView
{
    var delegate: CustomViewDelegate! = nil

    ・・・

    func hoge()
    {
        self.delegate.customMethod()
    }    
}

protocol CustomViewDelegate
{
    func customMethod() -> Void
}

修正したコード

呼び出し側はなにも手を加えていません

CustomView.swift

class CustomView: UIView
{
    weak var delegate: CustomViewDelegate! = nil // ★weakを追加

    ・・・

}

protocol CustomViewDelegate: class // ★classを追加
{
    func customMethod() -> Void
}

これでとりあえずViewContorllerが破棄されるべきときに、deinitが呼ばれるようになりました。
他にも対応しなくてはならない箇所が多々ありそうですが、とりあえず一歩前進したのでメモしておきました

以上です