手动操作 navigationController 的 viewControllers 数组时 iOS 手机崩溃

Posted

技术标签:

【中文标题】手动操作 navigationController 的 viewControllers 数组时 iOS 手机崩溃【英文标题】:iOS phone crashing when manipulating navigationController's viewControllers array manually 【发布时间】:2015-12-03 02:05:18 【问题描述】:

这一定是苹果的一个错误,但我希望有人能解决这个问题。我没有遇到典型的应用程序崩溃,我正在重启手机(带有苹果徽标的黑屏死机和所有内容)。这似乎与导航有关。

在我的 appDelegate 中,我有条件地将 loginController 推送到 didFinishLaunchingWithOptions 上的应用程序:

let appdelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)

let nav = appdelegate.window!.rootViewController as! UINavigationController
let loginLobby = mainStoryboard.instantiateViewControllerWithIdentifier("loginLobby")

if notLoggedIn 
    nav.pushViewController(loginLobby, animated: false)

然后我在情节提要中设置了一个 push segue,效果很好:

但是,当我从signUpViewController 按返回按钮返回loginLobby 时,手机会重新启动。

在我以标准故事板 segue 之外的其他方式操作 navigationStack 后,我在尝试释放 viewController 时,在其他几个场景中也经常遇到此错误。其他人有这个问题吗?

编辑:在这种特殊情况下,我没有收到任何错误消息:

Message from debugger: Terminated due to signal 15

在该错误的其他表现形式中,我收到了诸如 Terminating since there is no system app. 和偶尔的 XPC Connection Interrupted 之类的消息,没什么好说的。我启用了异常断点,但它们没有捕获任何东西。

edit:似乎有很多关于 rootView 是什么的问题。这是我设置为根的 UINavigationController 的另一个屏幕截图:

【问题讨论】:

【参考方案1】:

问题在于情节提要。我创建了一个新项目并布置了视图,一切似乎都运行良好。我在故事板源代码中发现了这几行,它们在工作版本和损坏版本之间并不常见:

<navigationItem key="navigationItem" id="wjx-jP-5kJ"/>
<keyCommands>
    <keyCommand/>
</keyCommands>

我不知道这些行应该做什么,也不知道它们是如何潜入我的故事板文件的,但它们是导致应用程序严重崩溃的原因,以至于手机不得不重新启动。我从我的主项目中删除了这些行,一切都恢复了。

【讨论】:

感谢您提交雷达://23743692。如果您添加一个键盘命令(UIViewController 的属性检查器)并将标题留空,这些行就会悄悄出现。这是 IB 中的一个错误,即此 XML 被写入并且没有警告它配置错误 (radar://23193389),并且 UIKit 中的一个错误导致崩溃导致设备重启 (radar://22874926)。 【参考方案2】:

你应该setViewControllers:animated: 而不是推。如果这不起作用,则需要在加载第一个视图控制器后操作视图控制器堆栈。

【讨论】:

崩溃一样...我能想出确保第一个视图控制器已加载的唯一方法是在 homeView 的 viewDidLoad 方法中推动它,但现在我尝试了,也会崩溃。【参考方案3】:

抱歉,我没有足够的声望,无法添加 cmets。

您是否在检查 loginLobby 是否为 nil

也许将其包装在 if let 中。

if notLoggedIn 
    if let loginLobby = mainStoryboard.instantiateViewControllerWithIdentifier("loginLobby") 
        nav.pushViewController(loginLobby, animated: false)
    

【讨论】:

我怀疑它是 nil,loginLobby 会正常推送,问题是当我将另一个 viewController 推送到 loginLobby 然后尝试弹回时。 啊,明白了。我相信 Apple 希望我们将一个视图控制器委派为根演示者,并从那里推送所有其他视图控制器。 loginLobby 是 UINavigationViewController 吗?如果没有,请尝试从 UINavigationController 变量 'nav' 呈现第二个视图控制器。 主情节提要的instanceViewController是什么 rootViewController 是一个 UINavigationController。 loginLobby 是 UIViewController 的子类(见屏幕截图)【参考方案4】:

您没有设置根视图控制器是否有原因?在我的实践中,当我有条件地在应用程序委托中设置窗口时,我会这样做:

self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let loginVc = storyboard.instantiateInitialViewController() as UIViewController!

if (/*something meets your criteria*/) 
    self.window?.rootViewController = loginVc


self.window?.makeKeyAndVisible()

【讨论】:

已经在情节提要中设置了根视图控制器。它是主导航控制器。

以上是关于手动操作 navigationController 的 viewControllers 数组时 iOS 手机崩溃的主要内容,如果未能解决你的问题,请参考以下文章

无法触发 Segue 手动加载 VC - self.navigationController 为 Nil?

在 navigationController 中有一个通用栏按钮项

IOS Swift以编程方式创建的navigationController TOOLBAR(底栏)项目操作不起作用

在 TabBarController 项中有一个 NavigationController

阻止用户返回 NavigationController

如何设置 subview-viewController 的 navigationController 属性?