我的Swift程序崩溃与EXC_BAD_INSTRUCTION和以下类似错误之一。这个错误是什么意思,我该如何修复它?

致命错误:在打开可选值时意外地发现nil

or

致命错误:在隐式地展开可选值时意外地发现nil


这篇文章旨在收集“意外发现为零”问题的答案,这样它们就不会分散而难以找到。请随意添加您自己的答案或编辑现有的wiki答案。


当前回答

This is because you are trying to use a value which can possible be nil, but you decided you don't want to have to check it, but instead assume its set when you uses it and define it as !, there are different philosophies on use of variable set as force unwrap, some people are against there use at all, I personal think they are ok for things that will crash all the time and are simple to reason about, usually references to resource, like outlets to xib files, or uses of images with you app that are part of your assets, if these are not set up properly, you app is going to crash straight away, for a very obvious reason, you can get into difficult when the order of objects being created can be uncertain, and trying to reason solutions to this can be difficult, it usually means a bad design as even it you make them optional, calls to you optional variable may not ever be executed, some projects can demand use of force unwraps for security reasons, things like banking apps, because they want the app to crash rather then continue to work in an unplanned way.

其他回答

简单地说 您正在尝试使用可选变量的值为nil。 快速修复可以使用保护或如果让而不是强制打开像放!在变量的末尾

Swift 5.7 +

如果让简写的影子一个现有的可选变量

以上回答清楚地解释了为什么会出现这个问题以及如何处理这个问题。但是从swift 5.7+开始,有了一种新的方式来处理这个问题。

是我的变量:整数?

以前

if let myVariable = myVariable {
    //this part get executed if the variable is not nil
}else{
    //this part get executed if the variable is nil
}

now

现在我们可以省略表达式的右边。

if let myVariable {
    //this part get executed if the variable is not nil
}else{
    //this part get executed if the variable is nil
}

以前,我们必须重复引用标识符两次,这可能导致这些可选绑定条件过于冗长,特别是在使用冗长的变量名时。

但是现在有一种简写语法,可以通过省略表达式的右边来实现可选绑定。

同样的事情也适用于guard let语句。

详情如下:

if-let简写的建议

Xcode 12 iOS 14 Swift 5

我的问题是导航类型,因为我直接调用vie控制器,而没有实例化故事板,这意味着数据还没有从故事板设置。

当你导航时,用

let homeViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "home") as? HomeEventsViewController
    homeViewController?.modalTransitionStyle = .crossDissolve
    homeViewController?.modalPresentationStyle = .fullScreen
    view.present(homeViewController ?? UIViewController(), animated: true, completion: nil)

希望它能起作用:-)

这是一个更重要的注释,这就是为什么隐式打开可选选项在调试nil值时可能具有欺骗性。

考虑下面的代码: 它编译时没有错误/警告:

c1.address.city = c3.address.city

然而在运行时,它给出以下错误:致命错误:在打开可选值时意外地发现nil

你能告诉我哪个对象是nil吗?

你不能!

完整的代码是:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        var c1 = NormalContact()
        let c3 = BadContact()

        c1.address.city = c3.address.city // compiler hides the truth from you and then you sudden get a crash
    }
}

struct NormalContact {
    var address : Address = Address(city: "defaultCity")
}

struct BadContact {
    var address : Address!
}

struct Address {
    var city : String
}

长话短说,使用var地址:地址!您隐藏了变量可以为nil的可能性,不让其他读取器看到。当它崩溃的时候,你会想“搞什么鬼?!”我的地址不是可选的,所以我为什么要崩溃?!

因此,最好这样写:

c1.address.city = c2.address!.city  // ERROR:  Fatal error: Unexpectedly found nil while unwrapping an Optional value 

你能告诉我哪个对象是nil吗?

这一次,代码对您来说更清楚了。您可以合理地认为,可能是强行打开了address参数。

完整的代码是:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        var c1 = NormalContact()
        let c2 = GoodContact()

        c1.address.city = c2.address!.city
        c1.address.city = c2.address?.city // not compile-able. No deceiving by the compiler
        c1.address.city = c2.address.city // not compile-able. No deceiving by the compiler
        if let city = c2.address?.city {  // safest approach. But that's not what I'm talking about here. 
            c1.address.city = city
        }

    }
}

struct NormalContact {
    var address : Address = Address(city: "defaultCity")
}

struct GoodContact {
    var address : Address?
}

struct Address {
    var city : String
}

如果在CollectionView中出现此错误,请尝试创建CustomCell文件和Custom xib。

在mainVC的ViewDidLoad()中添加此代码。

    let nib = UINib(nibName: "CustomnibName", bundle: nil)
    self.collectionView.register(nib, forCellWithReuseIdentifier: "cell")