簡體   English   中英

Swift iOS - 當作為子視圖控制器添加到另一個視圖控制器時,是否應該在子視圖控制器中調用 Deinit?

[英]Swift iOS -Should Deinit get called inside child View Controller when added as a child to another View Controller?

我在另一個 parentVC(vc1) 中的 parentVC(vc2) 中有一個 childVC(vc3)。 我這樣做是為了動畫目的。

發生的事情是我將 vc3 作為子項添加到 vc2。 我有一個推送 vc1 的 collectionView。 一旦 vc1 出現在場景中,vc2 就會被添加到其中。 當我從堆棧中彈出 vc1 並返回到 collectionView 時,vc1 中的 deinit 被調用,但是 vc2 中的 deinit 永遠不會被調用。

vc2 中的 deinit 是否應該被調用,即使它是 vc1 的子級? 或者可能是因為 thirdVC 在 secondVC 內部創建了對自身的強引用?

在其中添加了 ThirdVC 的 SecondVC:

class SecondController: UIViewController {

override func viewDidLoad() {
        super.viewDidLoad()

        let thirdVC = ThirdController()
        addChildViewController(thirdVC)
        view.addSubview(thirdVC.view)
        thirdVC.didMove(toParentViewController: self)
}

 // this never runs when the firstVC is popped off the stack
deinit{
     print("the secondVC has be deallocated")
}
}

集合視圖:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        let firstVC = FirstController()
        navigationController?.pushViewController(firstVC, animated: true)
    }

第一VC:

class FirstController: UIViewController {

override func viewDidLoad() {
        super.viewDidLoad()

        let secondVC = SecondController()
        addChildViewController(secondVC)
        view.addSubview(secondVC.view)
        secondVC.didMove(toParentViewController: self)
}

// this runs when popped off the stack
deinit{
     print("the firstVC has be deallocated")
}
}

我的問題的答案是是的,子視圖控制器的deinit也應該運行。 如果您在子視圖控制器中調用 deinit,並且當父級從場景中彈出(或被解雇)並且子級的 deinit 沒有運行時,那么您就有問題了。

正如@BadhanGanesh 在評論中指出的那樣,他問:

你是否在使用任何通知觀察者,你在不需要時沒有將它們移除

@Bruno Pinheiro 在評論中建議:

好像是很強的參考題

他們都是對的。 我查看了所有代碼,我以為我已經刪除了 KVO 觀察器,但我沒有。

長話短說,如果您有一個 View Controller 是另一個 View Controller(父級)的子級,那么一旦父級被釋放,子級也應該被釋放。

如果您在父對象或子對象中使用任何 KVO 觀察者,請確保刪除它們,否則您將創建一個強大的保留循環。

我需要將“弱自我”傳遞給父視圖控制器中的 firebase 觀察者以刪除保留周期,然后在父控制器和子控制器上調用 deinit:

    func observeFeatureChanged(){
    microbeRef.queryOrdered(byChild: Nodes.TIMESTAMP)
        .observe(.childChanged) { [weak self] (dataSnapshot) in
            if let featureDic = dataSnapshot.value as? [String: Any]{
                let featureName = dataSnapshot.key
                if let index = self?.featureNames.firstIndex(of: featureName){
                    self?.featureNames[index] = featureName
                    self?.featureDictionaries[index] = featureDic
                    let indexpath = IndexPath(item: index, section: 0)
                    self?.tableView.reloadRows(at: [indexpath], with: .automatic)
                }
            }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM