【问题标题】:Storyboard Controllers not Deallocating故事板控制器未释放
【发布时间】:2013-03-10 20:07:45
【问题描述】:

我的情节提要的初始视图控制器使用performSegue:withIdentifier 方法加载另一个视图控制器,然后使用相同的performSegue:withIdentifier 方法加载其他一些控制器。

但是,初始视图控制器和第二个视图控制器都没有释放。从仪器上看,它们的引用计数都倾向于 1。

当他退出应用程序时,我需要将用户发送回第一个控制器。到目前为止,我想到的唯一方法是使用 performSegue:withIdentifier 方法并将用户发送回初始控制器。

但是,我担心以前的控制器不会因此被释放,导致重新创建相同的视图控制器。

由于我需要注销用户回到第一个屏幕,我想确保所有以前的视图控制器都已被释放。

【问题讨论】:

    标签: iphone ios objective-c ios5 storyboard


    【解决方案1】:

    当您执行推送或模态转场时,它不会(也不应该)释放您正在转场的视图控制器。它需要保留它,以便当您弹出/关闭它时,它仍然存在。此规则的例外是在使用拆分视图控制器并且您使用替换转场时。但那是个特例。

    如果你想回到第一个场景,如果你正在使用导航控制器并且只使用 push segues,你可以使用popToRootViewControllerAnimated。 (对于 iOS 5 的目标,我会一直使用导航控制器,如果我不希望它可见就隐藏导航栏,因为这个原因。能够弹出多个级别很方便。实现相同的效果很麻烦模态segues。)在iOS 6中,您可以使用unwind segue,您可以在其中弹出/关闭任意数量的场景级别,例如,返回到您的初始场景。

    【讨论】:

      【解决方案2】:

      循环使用performSegue 不是一个好主意..

      如果您必须返回您的 VC 层次结构,您应该使用 UINavigationController 与推送/弹出 VC,或呈现/关闭模式 VC。您可以通过模态显示UINavigationController 将两者结合起来。

      【讨论】:

      • +1 同意。至少有两个例外:首先,在 iOS 6 中,您可以执行 performSegue 的 unwind segue。其次,如果使用拆分视图控制器的替换转场,同样没关系。但是您绝对正确,您永远不想要一组循环的推送/模态序列。
      • 感谢您确认我的想法。不过,您的答案更完整,因此为此+1。我以前没听说过 unwind segue,它看起来还不错。关于您链接到的答案的快速问题:在第 3 步中,您说“在 .m 中为视图控制器 A 实施操作”,不应该是 B 而不是 A 吗?
      • 没有。使用展开转场,您可以在视图控制器中定义要展开的展开动作(否则,如果您有十几个先前的场景,它怎么知道哪一个?)。 IB 计算出所有先前的场景及其关联的视图控制器,扫描 .m 文件以查找展开操作,获取这些名称,并显示您尝试添加的最终场景中的名称,这真的很酷放松赛格。顺便说一句,这也是为什么我喜欢给我的展开动作起有意义的名字,这样当你使用它们时,你可以清楚地知道你正在展开哪个场景。
      • 感谢您的信息。我得调查一下!
      【解决方案3】:

      在 iOS 6 之前,UIViewController 将保持活动状态,但其更昂贵的 UIView 将被释放以节省内存。与UIView 相比,UIViewController 本身相当轻巧。 从 iOS 6 开始你应该根据文档覆盖 didReceiveMemoryWarning

      UIViewController 的文档:

      内存管理

      内存是 iOS 中的关键资源,视图控制器提供 内置支持在关键时减少内存占用 次。 UIViewController 类提供了一些自动处理 通过其 didReceiveMemoryWarning 方法的低内存条件, 释放不需要的内存。

      在 iOS 6 之前,当出现内存不足警告时, 如果 UIViewController 类知道它可以重新加载或 稍后重新创建它们。如果发生这种情况,它还会调用 viewWillUnload 和 viewDidUnload 方法让你的代码有机会 放弃与您的视图关联的任何对象的所有权 层次结构,包括从 nib 文件加载的对象、创建的对象 在您的 viewDidLoad 方法中,以及在运行时延迟创建的对象和 添加到视图层次结构中。在 iOS 6 上,视图永远不会被清除并且 这些方法永远不会被调用。如果您的视图控制器需要 当内存不足时执行特定任务,它应该覆盖 didReceiveMemoryWarning 方法。

      只要您管理正确,就可以做出正确的反应(取决于 iOS 版本)并解除分配视图,我认为这里没有问题。

      【讨论】:

        猜你喜欢
        • 2015-06-14
        • 1970-01-01
        • 1970-01-01
        • 2012-03-10
        • 1970-01-01
        • 2013-01-10
        • 1970-01-01
        • 2014-06-26
        • 2013-02-03
        相关资源
        最近更新 更多