弹出时导航堆栈中的ViewController不会取消初始化,从而导致内存泄漏

时间:2019-04-10 13:56:11

标签: ios swift memory-leaks retain-cycle

在我的应用程序中,我有一个RootViewController,我的所有ViewController都是该子类的子类。开发时,通常在RootVC中使用它:

deinit { 
    print("\(type(of: self)) deinit")
}

,以便我始终可以看到我的任何viewController何时取消初始化。它打印:

  

MyExampleViewController deinit

今天,我注意到当我离开它时,其中一个并没有取消初始化。我们称之为DetailViewController。这是一个完全普通的(Root)ViewController子类,已插入主NavigationController中。在导航中点击Back button时,它会导航离开,但永远不会说它会取消初始化。这是第一个推送的控制器,因此我无法在弹出控制器之前先查看是否有帮助。但是,任何在之后推送的控制器在来回导航时都可以很好地初始化DetailViewController

我决定检查内存图,因此再次运行我的应用程序,将其推送到DetailViewController,然后通过单击导航中的Back button将其弹出,然后单击 Debug记忆图

在左侧的调试导航器中,向下滚动并看到存在DetailViewController的一个实例。如果我在打开内存图之前来回推了几次,则此DetailViewController的实例与我推和弹出的次数一样多。

单击它时,我会看到:

Memory Graph DetailViewController是最右边的单个控制器。我没有使用 Memory Graph (内存图),但是我认为“实线”白线是强项,而稍微透明的(灰色)线是弱项。这意味着我的控制者有一个强烈要求。底部的那个。

这是底行: Memory Graph 2

这是什么意思?似乎我的(自定义)NavigationController有一个名为_childViewControllers的数组,保留了我弹出的控制器。需要说明的是,我的自定义NavigationController中没有任何存储变量。只有子类可以覆盖5个功能,仅此而已。我有大约20个不同的ViewControllers被这个完全相同的自定义`NavigationController推送和弹出,但是它们都没有问题。

我读错图表了吗?必须有一个在图表中不可见的其他强烈要求,对吗?当我通过单击viewController“弹出” Back时,viewController是否应该删除我的_childViewControllers

1 个答案:

答案 0 :(得分:0)

终于弄清楚了。不幸的是,我不得不逐一注释掉几百行代码,直到我发现它何时开始按预期开始初始化。 问题是闭包中缺少[weak self],这并非出乎意料,但它属于完全不同的类,通过复杂的层次结构连接。