【问题标题】:Allocating UIViewControllers in viewDidLoad. Was this a mistake?在 viewDidLoad 中分配 UIViewControllers。这是一个错误吗?
【发布时间】:2011-12-06 09:03:45
【问题描述】:

我和一位同事一直在设计我们的代码,以便在我们的控制器对象的 viewDidLoad 方法中分配我们的视图控制器对象。我们做了很多,对象图看起来很好。一段时间后,我们发现需要在当前视图控制器层次结构之上添加另一个层,该层将拥有、分配和释放我们以前的父视图控制器。

这让我想到了内存不足警告和视图确实加载了。以前,我们的视图总是可见的,因此如果发生内存不足的警告就不会被释放,但现在有可能发生这种情况。如果是这样,似乎在重新加载视图时,它们将为新的视图控制器分配新的内存。

这会导致广泛的内存泄漏吗?或者我们使用保留声明的属性这一事实是否会拯救我们,因为旧的控制器将自动释放?我应该考虑哪些样式或约定?感谢您的帮助!

【问题讨论】:

    标签: ios cocoa-touch memory-management uiviewcontroller uikit


    【解决方案1】:

    如果你确实在 viewDidLoad 中创建了视图控制器,你应该在 viewDidUnload 中释放它们。几乎适用于任何对象,而不仅仅是视图控制器。

    但如果你说“Wut!?”,我不会感到惊讶。如果您的视图控制器需要通过内存警告来保持其状态,那么您不想释放它们。但是如果你用新的状态替换它们也不会更好。

    在 viewDidLoad 中创建视图控制器可能没有意义。在 initWithNibName:bundle: 中创建它们(并在 dealloc 中释放它们)。设计模式是视图控制器保持不变,它们的视图可以来来去去。如果您的从属视图控制器有任何内存密集型,则在其 viewDidUnload 中仅释放该对象。然后在出现内存警告时,您仍然会释放大量内存,但是您的所有视图控制器将保持在低内存使用状态,只保留少数标志、索引列表等,它们将需要在请求时恢复他们的视图。

    【讨论】:

    • 是的,保留控制器似乎更符合 MVC。谢谢你的建议:)
    【解决方案2】:

    如果您明确释放不再需要的每个视图控制器,则不会导致任何内存泄漏。通常,当您呈现视图控制器时,正在呈现的对象将为您保留控制器,因此如果您不再需要访问它,您可以释放它。但是,如果您使用的是 UINavigationController 并且您正在推送新的视图控制器,那么您应该实现 viewDidUnload 方法。这直接来自 Apple 的文档:

    在加载到内存后,视图控制器的视图会一直保留在内存中,直到内存不足或视图控制器本身被释放。在内存不足的情况下,如果当前未使用该视图,则默认 UIViewController 行为是释放存储在视图属性中的视图对象。但是,如果您的自定义视图控制器类存储指向视图层次结构中任何视图的出口或指针,则您还必须在释放顶级视图对象时释放这些引用。不这样做会阻止这些对象立即从内存中删除,并且如果您随后覆盖指向它们的任何指针,则可能会导致内存泄漏。

    您的视图控制器应始终清理对视图对象的任何引用的两个地方:

    dealloc方法 viewDidUnload 方法 如果您使用声明的属性来存储对视图的引用,并且该属性使用保留语义,则为其分配 nil 值足以释放视图。到目前为止,属性是管理视图对象的首选方式,因为它们很方便。如果您不使用属性,则必须在将相应的指针值设置为 nil 之前,向您明确保留的任何视图发送释放消息

    【讨论】:

    • 你是在建议我在 viewDidUnload 中释放视图控制器吗?
    • 您究竟是如何呈现视图控制器的?您是否尝试过实现 UINavigationController 或以模态方式呈现它?
    • 我们没有使用 UINavigationController。我们手动处理视图切换。
    • 我明白了。您可以在 viewDidUnloaddealloc 方法中释放控制器,但根据您设计应用程序的方式,它可能会导致一些问题。更好的方法是创建自定义 UIView 并在这些视图之间切换主要的 UIViewController。然后你可以释放当前不可见的视图。
    • 我可以这样做,但随后所有控制器功能都被挤到一个类中,使用起来很痛苦。感谢您的回答!
    猜你喜欢
    • 2011-03-10
    • 2012-09-18
    • 2012-03-25
    • 2010-12-22
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多