【问题标题】:Receive SIGABRT error when trying to hijack root view controller尝试劫持根视图控制器时收到 SIGABRT 错误
【发布时间】:2019-01-24 03:53:43
【问题描述】:

我试图让我的应用程序根据用户的 NSUserDefaults 中的数组是否为空来打开不同的视图控制器。本质上,如果用户之前在应用程序中保存了数据,应用程序将打开到他们可以选择数据的位置。否则,应用程序将打开一个欢迎屏幕。

但是,当数组为空时,我会看到我为欢迎屏幕设置的背景颜色,但看不到我在情节提要中布置的文本或按钮。当数组不为空并且数据页面应该打开时,我的应用程序会因 SIGABRT 错误而崩溃。我检查了有问题的视图控制器的所有插座,似乎没有任何东西断开连接。此外,当我注释掉应用程序委托中的代码并将数据视图控制器设置为我的初始启动视图时,应用程序运行良好。

完整的错误是“线程 1:信号 SIGABRT”,它被标记在 AppDelegate 类行中。

我在 App Delegate 中使用的代码如下:

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        var accounts = loadAccounts()!

        if accounts.isEmpty {
            let welcomeController = WelcomeViewController()
            self.window!.rootViewController = welcomeController
        } else {
            let tableController = AccountTableViewController()
            self.window!.rootViewController = tableController
        }

        return true
    }

    func loadAccounts() -> [Account]? {
        return NSKeyedUnarchiver.unarchiveObject(withFile: Account.ArchiveURL.path) as? [Account]
    }

【问题讨论】:

  • 为什么要强制解开调用loadAccounts的结果?如果它返回一个可选项,不要强行解包。
  • 究竟是哪一行导致了崩溃?完整的错误信息是什么?请在您的问题中填写这些详细信息(不要在评论中发布)。
  • 抱歉,我刚刚在问题中添加了完整的错误行。这和我之前在没有连接插座时收到的相同错误,但在解决此错误时我没有发现这种情况。
  • 您需要设置一个异常断点,以便您可以找出导致错误的确切行。你需要得到完整的错误信息。应该不仅仅是“SIGABRT”。
  • 您不能像这样简单地实例化视图控制器,因为它不会创建视图或控件。视图控制器可用于多个不同的故事板视图,因此您需要将视图控制器与实际视图相关联。你需要的是storyboard.instantiateViewControllerWithIdentifier()。见stackoverflow.com/a/26757245/1852207

标签: swift sigabrt rootviewcontroller


【解决方案1】:

可能是 UIWindow 设置不正确。

let bounds = UIScreen.main.bounds
self.window = UIWindow(frame: bounds)
self.window?.rootViewController = `your view controller`
self.window?.makeKeyAndVisible()

还有什么问题?

var accounts = loadAccounts()!

这条线是你的罪魁祸首。我猜正是这个符号!。您正在尝试从数据库或文件系统中获取数据并期望它始终存在。

想一想,不可能一直都是真的。

 # check if account array is not empty; I would have returned nil if it would be empty and so we can avoid that extra check here.
 if let accounts = loadAccounts(), !accounts.isEmpty {

     let tableController = AccountTableViewController()
     self.window!.rootViewController = tableController

     return true
 }

 let welcomeController = WelcomeViewController()
 self.window!.rootViewController = welcomeController

此外,如果您可以从调试控制台提供有关错误消息的更多信息。这样我就能以更好的方式提供帮助。

【讨论】:

  • 感谢您的建议!我刚刚用完整的错误更新了问题,该错误在类 AppDelegate 行中被标记。我不认为强制展开 loadAccounts 应该有任何问题,因为我正在使用的模拟器中有内容。无论如何,我已将其设为可选,但错误仍然发生。当我尝试修复 UIWindow 时也发生了错误。
  • 我认为ViewControllers 可能存在问题。检查你是否可以用虚拟数据打开那两个 viewController。
  • 我猜他们的意思是您在尝试解包之前尚未初始化 AppDelegate 的 window 属性。除非你在代码的其他地方这样做。
猜你喜欢
  • 2016-07-11
  • 2020-02-09
  • 1970-01-01
  • 2021-12-31
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多