重新启动应用程序会导致 NSInvalidArgumentException

restarting app causes NSInvalidArgumentException

因此,我对我的应用程序的全新安装进行了转接,显示了一个对话框,要求用户设置应用程序需要的一些变量。然后,对于管理员用户,我可以选择清除应用缓存然后重新启动应用,以便用户可以根据需要重做设置。

我使用下面的代码重新启动我的应用程序。

func restartApplication () {
       let viewController = SomeViewController()
       let navCtrl = UINavigationController(rootViewController: viewController)

       guard
           let window = UIApplication.shared.keyWindow,
           let rootViewController = window.rootViewController
           else {
               return
       }

       navCtrl.view.frame = rootViewController.view.frame
       navCtrl.view.layoutIfNeeded()

       UIView.transition(with: window, duration: 0.3, options: .transitionCrossDissolve, animations: {
           window.rootViewController = navCtrl
       })

   }

有效。但是当应用程序到达 viewDidAppear() 并需要显示我的对话框时,应用程序崩溃并显示

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 
'Receiver (<AppName.SomeViewController: 0x150dda00>) has no segue with identifier 'showSetup''

我想我在重新启动时搞砸了一些事情,或者我仍然需要做一些事情才能让它工作,但我不知道是什么。

我目前正在将我的 android 应用程序转换为 iOS,所以我想做我可以转换的所有事情。

这就是我进行转场的方式。

DispatchQueue.main.async {
   self.performSegue(withIdentifier: "showSetup", sender: self)
}

由于您的 "relaunched" 视图控制器不是来自情节提要,因此对 segues(依赖于情节提要)的任何引用都将失败。

你需要这样的东西:

func restartApplication () {
   let navCtrl = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("NavController")

   guard
       let window = UIApplication.shared.keyWindow,
       let rootViewController = window.rootViewController
   else {
           return
   }

   navCtrl.view.frame = rootViewController.view.frame
   navCtrl.view.layoutIfNeeded()

   UIView.transition(with: window, duration: 0.3, options: .transitionCrossDissolve, animations: {
       window.rootViewController = navCtrl
   })

}