繁体   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