【问题标题】:iPhone - UINavigationController, reuse views?iPhone - UINavigationController,重用视图?
【发布时间】:2009-10-26 05:45:17
【问题描述】:

根本问题是“您可以在导航堆栈上推送多少个 UIViewController?”不会导致内存警告或导致看门狗终止。

假设我有一个应用程序,它基本上是三个实体的数据库,每个实体都可以与其他实体建立关系,并且关系显示在 UIViewController 上。用户可以遵循这些关系,每个人都会带来一个新的控制器 - 如果实体是 A、B 和 C 以及 A->B->C->B->C->A,那么每种视图都在堆栈上两次.我了解如何推送和弹出,如何推送回特定的控制器,我认为与其无限扩展导航堆栈,不如在导航堆栈中重用视图控制器。

为此,每次我想要 FirstEntityViewController 时,我都可以扫描导航堆栈以找到 [self isKindOfClass:[FirstEntityViewController class]]; 所在的对象,然后调用旨在将视图重新调整为我当前想要查看的方法 - 只需刷新与重用 UITableViewCell 时的方式相同。

这很好,除了它可能对 NavigationController 有影响。如果我使用UINavigationController:popToViewController:animated:,我认为它将丢弃我弹出的视图上方的所有内容,包括用户希望在导航栏中点击“返回”时找到的视图。所以用户点击一个关系,点击返回然后“嗯?”

如果我从导航堆栈中删除匹配的控制器,然后将其弹出到堆栈顶部,只要用户不返回到已移动的 FirstEntityViewController 实例或否则再次导航会显得不一致。

将控制器从堆栈中移除,并以某种方式在堆栈中保留一个位置,以便在弹出重复使用的控制器时可以将其替换回原来的位置,这是正确的解决方案吗?我是否应该维护自己的视图类型和数据显示列表,以便在弹出时我可以替换即将弹出的视图下方的视图,比返回导航领先一步?

或者这太复杂了?甚至不需要担心这种情况,因为操作系统会重用大部分视图控制器,就像重用 UITableViewCells 一样,并且拥有 50 深的导航堆栈并没有真正的内存或性能影响?

【问题讨论】:

  • 听起来有两个问题:1)堆栈上可以有多少东西,2)给定的东西可以在堆栈上多次吗?对吗?
  • 有点。肯定有多少东西可以在堆栈上。一个给定的东西可以在堆栈上多次出现吗?我相当确定答案是肯定的,我只是担心允许它的影响(即 didReceiveMemoryWarning)。解决方案可能是等待该内存警告,然后开始寻找要杀死的堆栈条目,例如最后一个“重要”视图之前的所有内容。

标签: iphone cocoa-touch uinavigationcontroller


【解决方案1】:

ViewController 实例保留在 UINavigationController 的堆栈中,但除了顶视图之外的任何视图都可以随时卸载(视图控制器通过 viewDidUnload 消息通知)。

换句话说,顶视图下面的视图不会闲置,最终会在内存不足的情况下被卸载,因此您无需尝试重​​用视图控制器。

【讨论】:

  • 当视图被卸载时导航会发生什么 - 链接到丢失的视图并且仍然允许返回或返回不再是一个选项?
  • 没有。当视图再次出现时,它会通过 loadView 和 viewDidLoad 消息重新加载。您可以通过模拟内存不足的情况在模拟器中进行测试。
【解决方案2】:

最后我检查了你不能将已经在导航控制器堆栈上的视图控制器再次推回它。您必须创建一个新的视图控制器并将其推入堆栈,每个后退按钮都会将其从堆栈中弹出。您能做的最好的事情是制作视图控制器的缓存并根据需要将它们分发出去——只要它们从导航控制器堆栈中弹出。但它可能不会通过节省内存来为您带来太多好处。

UITableViews 有点不同,因为在任何给定时间只有相对少量的单元格在视图中,并且一旦单元格离开屏幕,它就会被移除并返回到池中。如果你能保证你的链的最大深度是固定的,那么你可以拉一个类似的窗口方案。如果没有,您可能必须坚持深入并警惕尽快释放内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-13
    • 1970-01-01
    相关资源
    最近更新 更多