在我的应用程序中,我有一个 RootViewController
我的所有 ViewController 都是它的子类。开发时,我通常在我的 RootVC 中使用它:
deinit {
print("\(type(of: self)) deinit")
}
这样我总是可以看到我的任何viewControllers何时deinit。它打印:
MyExampleViewController deinit
今天,我注意到其中一个当我离开它时并没有取消初始化。我们将其称为 DetailViewController
。它是一个完全正常的(根)ViewController 子类,被插入主 NavigationController
中。当点击导航中的后退按钮
时,它会导航离开,但不会说它会取消初始化。这是第一个推送的 Controller ,因此我之前无法弹出 Controller 以查看是否有帮助。但是,在来回导航时,在 DetailViewController
之后推送的任何 Controller 都会被很好地定义。
我决定检查内存图,因此我再次运行我的应用程序,推送到 DetailViewController
,然后通过单击导航中的后退按钮
将其弹出,然后我单击调试内存图。
在左侧的调试导航器中,我向下滚动并看到存在一个 DetailViewController
实例。如果我在打开内存图之前来回推送几次,则此 DetailViewController
的不同实例与我推送和弹出的次数一样多。
当点击它时,我看到这个:
DetailViewController
是最右侧的单个 Controller 。我没有太多地使用内存图,但我认为“实”白线是强声明,而稍微透明的(灰色)线是弱声明。这意味着我的 Controller 有一个强烈的要求。位于底部的那个。
这是什么意思?看起来我的(自定义)NavigationController 有一个名为 _childViewControllers 的数组,它保留了我弹出的 Controller 。澄清一下,我的自定义 NavigationController
中没有任何存储变量。它仅被子类化以覆盖 5 个函数,仅此而已。我有大约 20 个不同的 ViewControllers 被这个完全相同的自定义“NavigationController”推送和弹出,但它们都没有问题。
我看错了图表吗?一定有一个在图表中看不到的不同的强有力的主张,对吗?当我通过点击返回
“弹出”viewController
时,我的viewController
不应该被_childViewControllers
删除吗?
最佳答案
终于明白了。不幸的是,我不得不一点一点地注释掉几百行代码,直到我发现它何时开始按预期取消初始化。
问题是闭包中缺少 [weak self]
,这并不意外,但它位于完全不同的类中,通过复杂的层次结构连接。
关于ios - 导航堆栈中的ViewController在弹出时不会取消初始化,导致内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55614403/