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



我有一个由两种主要控制器类型组成的应用程序:

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

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

"我以为应用程序会在内存中保存以前的所有控制器,以允许UINavigationController的后退按钮按预期操作?">

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

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

破解了!

这里的问题出现在我的应用程序中其他地方的逻辑中。您将看到该页面是从page.currentPage.设置的

page = Page.currentPage

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

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

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

最新更新