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

标签 ios swift memory-leaks retain-cycle

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

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

这样我总是可以看到我的任何viewControllers何时deinit。它打印:

MyExampleViewController deinit

今天,我注意到其中一个当我离开它时并没有取消初始化。我们将其称为 DetailViewController。它是一个完全正常的(根)ViewController 子类,被插入主 NavigationController 中。当点击导航中的后退按钮时,它会导航离开,但不会说它会取消初始化。这是第一个推送的 Controller ,因此我之前无法弹出 Controller 以查看是否有帮助。但是,在来回导航时, DetailViewController 之后推送的任何 Controller 都会被很好地定义。

我决定检查内存图,因此我再次运行我的应用程序,推送到 DetailViewController,然后通过单击导航中的后退按钮 将其弹出,然后我单击调试内存图

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

当点击它时,我看到这个:

Memory Graph DetailViewController 是最右侧的单个 Controller 。我没有太多地使用内存图,但我认为“实”白线是强声明,而稍微透明的(灰色)线是弱声明。这意味着我的 Controller 有一个强烈的要求。位于底部的那个。

这是底行: Memory Graph 2

这是什么意思?看起来我的(自定义)NavigationController 有一个名为 _childViewControllers 的数组,它保留了我弹出的 Controller 。澄清一下,我的自定义 NavigationController 中没有任何存储变量。它仅被子类化以覆盖 5 个函数,仅此而已。我有大约 20 个不同的 ViewControllers 被这个完全相同的自定义“NavigationController”推送和弹出,但它们都没有问题。

我看错了图表吗?一定有一个在图表中看不到的不同的强有力的主张,对吗?当我通过点击返回“弹出”viewController时,我的viewController不应该被_childViewControllers删除吗?

最佳答案

终于明白了。不幸的是,我不得不一点一点地注释掉几百行代码,直到我发现它何时开始按预期取消初始化。 问题是闭包中缺少 [weak self],这并不意外,但它位于完全不同的类中,通过复杂的层次结构连接。

关于ios - 导航堆栈中的ViewController在弹出时不会取消初始化,导致内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55614403/

相关文章:

ios - 应用内购买重定向到另一个 View Controller

ios - Mailcore2 - 从特定日期开始搜索电子邮件

ios - MKMapView 位置不会更新

ios - 制图将约束设置为变量

ios - 在 TableView 单元格中处理从 Firebase 检索数据的更好方法

swift - 将 URL 的常量部分作为变量对所有 View Controller 可用

ios - Swift 3 创建一个 NSNumber 对象

ios - Xcode静态分析器显示的困难

ios - UIViewController 变量在解除分配后仍然存在

c++ - IDXGISwapChain::存在内存泄漏