让第三个视图控制器显示崩溃我的应用程序 - Xcode

Getting third View Controller to display crashes my app - Xcode

我有 4 个视图控制器:,SwitchingViewController 负责我在不同视图之间的所有视图切换。我有一个黄色视图、一个蓝色视图和一个绿色视图。该应用程序已经可以在黄色和蓝色视图之间正常切换,但是当我尝试切换到绿色视图时,它会因错误而崩溃。 Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value.

故事板和应用程序如下所示:

phone 左下角的切换视图按钮是控制视图切换的,但同样它只适用于从黄色到蓝色,然后从蓝色到绿色崩溃。

这是我的 SwitchingViewController.swift,我认为问题可能出在第 79 行,但我不确定到底是什么。

class SwitchingViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
//        blueViewController =
//            storyboard?.instantiateViewController(withIdentifier: "Blue")
//            as! BlueViewController
//        blueViewController.view.frame = view.frame
//        switchViewController(from: nil, to: blueViewController)
        yellowViewController =
            storyboard?.instantiateViewController(withIdentifier: "Yellow")
            as! YellowViewController
        yellowViewController.view.frame = view.frame
        switchViewController(from: nil, to: yellowViewController)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        
        if blueViewController != nil && blueViewController!.view.superview == nil {
            blueViewController = nil
        }
        if yellowViewController != nil && yellowViewController!.view.superview == nil {
            yellowViewController = nil
        }
        if greenViewController != nil && greenViewController!.view.superview == nil {
            greenViewController = nil
        }
    }
    
    private var blueViewController: BlueViewController!
    private var yellowViewController: YellowViewController!
    private var greenViewController: GreenViewController!
    
    @IBAction func switchViews(sender: UIBarButtonItem) {
        if yellowViewController?.view.superview == nil {
            if yellowViewController == nil {
                yellowViewController =
                    storyboard?.instantiateViewController(withIdentifier: "Yellow")
                    as! YellowViewController
            }
        } else if blueViewController?.view.superview == nil {
            if blueViewController == nil {
                blueViewController =
                    storyboard?.instantiateViewController(withIdentifier: "Blue")
                    as! BlueViewController
            }
        } else if greenViewController?.view.superview == nil {
            if greenViewController == nil {
                greenViewController =
                    storyboard?.instantiateViewController(withIdentifier: "Green")
                    as! GreenViewController
            }
        }
        
        UIView.beginAnimations("View Flip", context: nil)
        UIView.setAnimationDuration(0.4)
        UIView.setAnimationCurve(.easeInOut)
        // Switch view controllers
        if yellowViewController != nil
                    && yellowViewController!.view.superview != nil {
            UIView.setAnimationTransition(.flipFromRight, for: view, cache: true)
            blueViewController.view.frame = view.frame
            switchViewController(from: yellowViewController, to: blueViewController)
        } else if blueViewController != nil
                    && blueViewController!.view.superview != nil {
            UIView.setAnimationTransition(.flipFromRight, for: view, cache: true)
            greenViewController.view.frame = view.frame
            switchViewController(from: blueViewController, to: greenViewController)
        } else {
            UIView.setAnimationTransition(.flipFromRight, for: view, cache: true)
            yellowViewController.view.frame = view.frame
            switchViewController(from: greenViewController, to: yellowViewController)
        }
        UIView.commitAnimations()
        
    }
    
    private func switchViewController(from fromVC:UIViewController?, to toVC:UIViewController?) {
        if fromVC != nil {
            fromVC!.willMove(toParent: nil)
            fromVC!.view.removeFromSuperview()
            fromVC!.removeFromParent()
        }
        
        if toVC != nil {
            self.addChild(toVC!)
            self.view.insertSubview(toVC!.view, at: 0)
            toVC!.didMove(toParent: self)
        }
    }

}

最后,这是崩溃报告的图片:

任何帮助都有助于弄清楚为什么它会因该错误而崩溃,如果需要其他信息以更好地理解,请告诉我。

你的问题是这些行:

private var blueViewController: BlueViewController!
private var yellowViewController: YellowViewController!
private var greenViewController: GreenViewController!

您将变量 blueViewControlleryellowViewControllergreenViewController 声明为“隐式展开的可选值”。 (类型后面的 !。)

这告诉编译器“相信我。这个变量是可选的,但我绝对确定在我的代码运行时它永远不会为零。我很如果我错了,你肯定会崩溃。"

去掉所有感叹号。我将“隐式解包可选”运算符和密切相关的强制解包运算符称为“如果为零则崩溃”运算符,因为它们就是这样做的。

在你真正、真正理解可选值之前,你应该像避免瘟疫一样避免这两种情况。每次使用可选项时都需要解包,但不这样做可能会造成像这样的崩溃。