从父级删除后保留的子视图控制器

Posted

技术标签:

【中文标题】从父级删除后保留的子视图控制器【英文标题】:Child view controller retained after being removed from parent 【发布时间】:2019-08-20 20:10:38 【问题描述】:

在一个针对 ios 12 的 Swift 项目中,我有一个子视图控制器,它在从其父视图中删除后(以及在其视图从 .superview 中删除后)被保留。

Xcode 的内存调试器显示如下:

右侧的选定对象 (IAIARViewController) 是意外保留的对象。我假设暗线/箭头表示强引用,浅灰色的(例如来自 SCNRenderer)表示弱引用,这意味着保留实例的罪魁祸首是 ViewController 的 _childViewControllers NSMutableArray 存储。

但是,当我打印 NSMutableArray(链中最接近 IAIARViewController 实例的那个)的描述时,我得到:

Printing description of $20:
<__NSArrayM 0x112e12370>(
    <***.IAIChartViewController: 0x113226400>,
    <***.IAIMapViewController: 0x113093400>
)

即数组中没有 IAIARViewController 的实例(内容是我所期望的。)

这似乎是来自 Xcode Memory Graph Debugger 的错误信息。还有什么可能导致 IAIARViewController 被保留?

【问题讨论】:

您可以打开malloc调试并运行应用程序以记录保留和释放并在内存图中读取它们。还要检查是否有泄漏。 感谢 Matt - malloc 看起来完全符合预期(只是一个实例),并且内存图调试器或仪器中没有显示泄漏。我怀疑 Storyboards 或 SceneKit 现在正在多个视图控制器中使用。根据顺序,我有时会看到由 _externalObjectsTableViewForLoading(内部 UIViewController 属性)或 C3DEnginePipeline(SceneKit/Metal 内部的东西)保留的实例。 你有解决这个问题的办法吗,因为我确实有这个问题。@StephenT 【参考方案1】:

您可以尝试对控制器的属性(vars)一一进行注释,看看它是否仍然被它们保留。我认为问题出在这些属性之一上。

您还可以使用仪器检查泄漏(查看屏幕截图)。它可以为您提供更详细的信息。

【讨论】:

谢谢 Nik - 您指的是哪个视图控制器,为什么您认为属性 var 可能是问题所在? 我建议,保留 VC 的某些属性会产生保留循环。 OK - 我在内存图调试器(或 Instruments/Leaks)中没有看到任何表明它是泄漏(没有感叹号)或保留周期(没有显示周期)的东西,每个瑟。可以这么说,它更像是一种无法解释的保留。我会继续挖掘!

以上是关于从父级删除后保留的子视图控制器的主要内容,如果未能解决你的问题,请参考以下文章

尝试从父级 IOS swift 3 中删除子级时,我的代表为零

如何使用从父级继承的句柄创建提升的子进程

Swift - 将数据从父视图控制器传递到子视图控制器

如何使引导树视图从父级折叠到子级?

在 iOS 的子视图控制器中调用方法

从父级获取过滤的子级