如何阻止此UINavigationController释放视图控制器

时间:2012-11-14 22:50:02

标签: objective-c ios xcode uinavigationcontroller rubymotion

我有一个应用程序,包含2种主要控制器类型:

1)UITableViewController - 充当导航屏幕 2)UINavigationController中包含的UIViewController - 显示主应用程序内容。

TableViewController内容看起来有点像这样:

  • Page 1
  • Page 2
  • 第3页 ......等等。

我在AppDelegate上定义了一个属性 - 一个名为PageViewControllers的数组。 当应用程序启动时,会为应用程序中的每个 Page 创建一个新的UIViewController实例。

第一个 Page 的控制器被设置为UINavigationController的rootViewController。

当用户在UITableView控制器中选择一行时,UINavigationController会推送或弹出该行的相关视图控制器。 (如果我点击" Page 3",它会将 Page 三个推送到控制器。)

我有这个工作得很好 - 唯一的问题是当尝试跳回导航堆栈时,应用程序偶尔会崩溃。例如,从 Page 15到 Page 2

我收到的错误消息是:

*** Terminating app due to uncaught exception 'RuntimeError', reason: 'NSInternalInconsistencyException: Tried to pop to a view controller that doesn't exist.

我认为UINavigationController可能会释放一些控制器。我认为该应用程序会将所有以前的控制器保存在内存中,以允许UINavigationController的后退按钮按预期运行?

知道如何防止这种情况发生,或者我有什么遗漏?

更新

这是我选择表格行后推送/弹出导航控制器的代码。 (这是Rubymotion)

def tableView(tableView, didSelectRowAtIndexPath: indexPath)
  # first we need to work out which controller was selected...
  page = Page.current

  currentPageController      = appDelegate.pageControllers[page.absoluteIndex]
  currentPageControllerIndex = appDelegate.pageControllers.index(currentPageController)

  nextPageController      = appDelegate.pageControllers[Page.pageAtIndexPath(indexPath).absoluteIndex]
  nextPageControllerIndex = appDelegate.pageControllers.index(nextPageController)

  case
  # When we're moving forward in the stack... 
  when currentPageControllerIndex < nextPageControllerIndex
    for controller in appDelegate.pageControllers[(currentPageControllerIndex + 1)..nextPageControllerIndex]
      # push the next controller on to the nav stack, only animate if it's the last one
      appDelegate.rootViewControllerNav.pushViewController(controller, animated: controller == nextPageController)        
    end

  # When we're moving backward in the stack...
  when currentPageControllerIndex > nextPageControllerIndex
    appDelegate.rootViewControllerNav.popToViewController(nextPageController, animated: true)

  # When we select the same step again...
  else
    NSLog("Selected the same page")
  end

  # close the side menu afterwards
  appDelegate.rootViewControllerNav.sideMenu.toggleSideMenuPressed(self)
end

2 个答案:

答案 0 :(得分:0)

“我认为该应用程序会将所有以前的控制器保存在内存中,以允许UINavigationController的后退按钮按预期运行?”

只要您继续前进,这是正确的 - 当您推送新的视图控制器时,它会将新的视图控制器添加到堆栈中的前一个视图控制器上。但是,当你使用popViewController时,它会从堆栈中删除,如果你没有强引用它,它将被释放。所以,如果你去1 - &gt; 2 - &gt; 3 ........-&gt; 15然后弹出2,它应该可以工作,但是如果你做这样的事情:

1 - &gt; 2 - &gt; 3 popTo 1然后按到 - > 15然后弹出到2,2和3都不再存在。 因此,您应该注意在表格中拾取单元格的顺序,并注意何时出现错误。看看它是否符合这个解释。

答案 1 :(得分:0)

破解了!

这里的问题出在我应用中的其他地方。您会看到该页面是从 Page.currentPage 设置的。

page = Page.currentPage

Page.currentPage 应始终设置为当前显示的页面。

设置当前页面的代码位于PagesViewController的viewDidLoad方法中,而不是viewDidAppear:动画方法 - 意味着一个页面已被查看,它不会再次设置Page.currentPage。

现在修复 - 非常感谢分享的想法和提示!