[英]Swift iOS -View Controller deinit runs when adding it to a new keyWindow
[英]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.