UIViewController 在 dealloc 时不释放子视图(使用 ARC)

Posted

技术标签:

【中文标题】UIViewController 在 dealloc 时不释放子视图(使用 ARC)【英文标题】:UIViewController not releasing subviews when dealloc (using ARC) 【发布时间】:2012-01-13 15:57:37 【问题描述】:

我的 UIViewController 似乎有一个奇怪的(非?)问题。似乎控制器在被释放时没有释放其子视图。我将 NSLog 消息放置在所有子视图的 dealloc 方法以及视图控制器中。视图控制器 dealloc 被调用,但子视图没有。但是,如果我随后将该视图控制器的另一个实例推送到导航堆栈,则似乎前一个实例的所有子视图随后都被释放(我在控制台中收到一堆 NSLog 消息让我知道)。我已经检查过了,我没有单独引用呈现视图控制器(正在执行推送的那个)中的自定义视图控制器。

一个小(可能)细节:自定义视图控制器确实接收到它存储的块,然后在弹出之前执行。但是,我确实向它发送了 nil 并且我得到了相同的行为。另外,当前视图控制器在弹出堆栈时会解除分配,因此没有保留周期。

另外,我确实尝试在自定义视图控制器的 dealloc 方法中显式释放每个视图。同样的行为。

导航控制器是否可能会保留它?我的任何其他视图控制器似乎都没有这样做。

我的问题是这确实代表了内存泄漏(所有这些子视图);虽然泄漏没有叠加,但它仍然是泄漏。

【问题讨论】:

小例子很有帮助。 我同意@Joe,分享一些代码。特别是,我以前遇到过块泄漏的问题。如果您将其设置为 nil,这应该不是问题,除非该代码路径不执行。 抱歉缺少示例,但这与两个类有关,总共大约 1,000 行代码,我不知道该代码的哪里出现问题。跨度> 道德+1。不过,您应该把它作为答案并接受它,这样人们就知道这个问题已经结束了。 它不会让我发布我自己的问题的答案。我会在大约 5 小时内 :) 【参考方案1】:

好吧,这很尴尬。我确实在我无意中用作集合类的另一个类(称为 ViewDef)中发现了问题。当我第一次弄清楚一些动画时(几个月前),这是一种快速而肮脏的方式来跟踪我的子视图。 ViewDef 存储从数据库中检索的帧/字体/颜色/等信息,因此在确定动画(方向之间)时也可以方便地存储视图。这些 ViewDef 由我的模型存储并传递,所以当然视图也被保留(稍后被另一个视图控制器替换)。无论如何,我忘了在我的代码中插入一个警告以便稍后解决这个问题。

故事的寓意:如果你打算做一些愚蠢的事情,至少要记录你的愚蠢,这样你以后就不必在互联网上传播它了。

【讨论】:

【参考方案2】:

您可以尝试在 viewDidUnload 方法中将子视图设置为 nil,这可能会有所帮助

【讨论】:

【参考方案3】:

要尝试的一件事是确保您的所有子视图代表都设置为 nil。

【讨论】:

实际上,我的子视图没有代表。它们都是使用块的自定义视图。即便如此,这将导致自定义视图控制器的保留周期,该控制器正在被释放。

以上是关于UIViewController 在 dealloc 时不释放子视图(使用 ARC)的主要内容,如果未能解决你的问题,请参考以下文章

如何在通用 UIViewController 之后设置自定义 UIViewController?

iOS:如何在弹出其子 UIViewController 后“刷新” UIViewController?

iPad 应用程序,如何在 uiviewcontroller 之上显示 uiviewcontroller

如何在 UITabBarViewController 中的 UINavigationController 中深度链接到从 UIViewController 访问的 UIViewController?

尝试在其视图不在窗口层次结构中的 UIViewController 上呈现 UIViewController

尝试在其视图不在窗口层次结构中的 UIViewController 上呈现 UIViewController