0

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

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

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

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

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

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

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

我的这个运行良好 - 唯一的问题是应用程序在尝试跳回导航堆栈时偶尔会崩溃。例如,从15 页到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
4

2 回答 2

0

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

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

1-->2-->3 popTo 1 然后 push to-->15 然后 pop 到 2,2 和 3 都不会再存在了。因此,您应该注意在表格中选择单元格的顺序,并注意何时出现错误。看看是否对应这个解释。

于 2012-11-15T04:13:33.017 回答
0

破解它!

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

page = Page.currentPage

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

设置当前页面的代码在 PagesViewController 的 viewDidLoad 方法中,而不是 viewDidAppear:animated 方法中——这意味着已经查看了一个页面,它不会再次设置 Page.currentPage。

现已修复 - 非常感谢分享的想法和技巧!

于 2012-11-15T10:09:59.860 回答