在 Swift 中对 Optional 值进行测试后解包时出错

Posted

技术标签:

【中文标题】在 Swift 中对 Optional 值进行测试后解包时出错【英文标题】:Error while unwrapping an Optional value after testing it in Swift 【发布时间】:2014-10-28 22:34:54 【问题描述】:

今天早上我在运行我的代码时遇到了一个奇怪的错误。

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

这是我的简单对象:

class FQ 

    var rating: Float?
    var phone: String?

    init(rating: Float?, phone: String?)
    
        self.rating = rating
        self.phone = phone
    

但我在 if 语句 (FQ.match() -> FQ?) 中测试 nil 值:

let fq: FQ? = FQ.match(self.place!.name, location: self.place!.location)

if fq != nil && fq!.phone != nil 
    self.phone.text = fq!.phone
 else 
    self.phone.text = ""

但是调试它:

fq 的打印说明:(project.FQ?) fq = Some 评分 = 6.0999999 电话=“+33 1 53 10 87 19”

该值不为零。 使用电话号码设置标签值时调试器失败。

我以为我理解 Optional,但看起来我没有。我错过了什么?

【问题讨论】:

【参考方案1】:

如果你说fq不是nil,那么只有一个地方可以产生异常:

self.phone.text = fq!.phone

self.phoneUILabel(或类似名称)吗?如果是,我认为这是一个隐式展开的

@IBOutlet var phone: UILabel!

你确定它不是 nil 吗?

【讨论】:

我认为他们最终转换了 Objc API 中所有隐式展开的内容?但如果不是最新版本的 Swift,这可能是答案。 我发现了问题。我的 UIlabel 声明得很好,但我猜在合并期间出口链接消失了。我必须将我的标签链接到我的控制器,现在它工作正常。错误消息有点令人困惑和误导。 @AlvinThompson:自定义视图控制器、视图等中的 UI 组件始终是(隐式展开的)可选项,因为它们不是在实例化时创建的,我认为这不会改变。 @maxwell2022:一般来说编译消息通常是神秘的和误导性的——但在这种情况下,很明显它是关于一个未包装的可选项为 nil。原因可能是缺少出口链接。 @Antonio:我明白了!我还没走到那一步。【参考方案2】:

这是一个误导性的错误消息。

我的插座在我看来是正确声明的,但不知何故 UI 和控制器之间的联系消失了。我认为它发生在 Git 合并之后。

我只需要将标签链接回选择我的电话插座变量的视图,现在一切正常。

谢谢各位, 马克西姆

【讨论】:

【参考方案3】:

看来fq.phone 也是一个可选的,所以你不能将它分配给self.phone.text(我假设不是可选的)而不先打开它。试试:

self.phone.text = fq!.phone!

【讨论】:

以上是关于在 Swift 中对 Optional 值进行测试后解包时出错的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 测试驱动开发中对 @ObservableObject 进行单元测试

如何在 Swift 中对这个自定义 UITextField 进行单元测试?

如何在 Swift 中对私有或内部函数进行单元测试?

在 Swift 中对私有变量进行单元测试

在 Swift 中对符合协议的对象和变量进行单元测试

swift中的optional