实例化的可选变量在 Xcode 调试器中显示为 nil

Posted

技术标签:

【中文标题】实例化的可选变量在 Xcode 调试器中显示为 nil【英文标题】:Instantiated optional variable shows as nil in Xcode debugger 【发布时间】:2020-01-26 06:16:50 【问题描述】:

自从我升级到 Xcode 11 和 Swift 5.1 后,我遇到了一个奇怪的问题——在一个可选变量被实例化之后,它仍然可以在 Xcode 调试器中显示为 nil!

我有一个名为 booking 的可选类变量:

var booking: Booking?

它的类型是Booking:

public struct Booking: Codable 
    var id: Int?
    var start_time: Date?
    var payment_currency: String = "USD"
    var payment_amount: Int?

当我单步执行代码时,我可以在分配之前看到booking...它为零,太棒了:

那么在分配之后...什么,还是nil??:

我想知道它是否以某种方式被视为一个惰性变量。但它并不是真正的 nil,因为它可以访问:

搜索了一段时间后,我想知道我在 Xcode 中的构建模式是否没有设置“调试可执行文件”标志。但确实如此。我什至在打开和关闭标志的情况下清理并重建了项目,以确保。

无论我在变量视图中查看booking 还是在控制台视图中输入p booking,它都显示为nil。

这里发生了什么?我需要在此升级之前进行调试的可预测性。

更新

我提炼出一种简单的方法来重现该问题。首先,创建一个空的单视图项目并将其添加到 AppDelegate.swift 的顶部:

public struct Booking: Codable 
    var start_time: Date?
    var payment_currency: String = "USD"

然后将这些行添加到 application(_:didFinishLaunchingWithOptions:) func:

booking = Booking()
print("booking.payment_currency = \(booking?.payment_currency ?? "NULL")")

像之前一样设置断点,在运行时,请注意即使在分配后调试器也会显示预订为零,就像我原来的情况一样。

然后注释掉start_time 变量,重新运行,并注意现在调试器显示booking 在被赋值后具有一个值,正如预期的那样。

因此,看起来像这样的结构中的 Date 变量,无论是否可选,都会使调试变得混乱。特别是日期变量——将变量更改为其他类型,如 Int、Int?、String、String?... 并且没有问题。

除非我遗漏了一些非常基本的东西,否则这对我来说似乎是 Xcode 调试器中的一个错误。如果是这样,最好的举报方式是https://developer.apple.com/bug-reporting/吗?

【问题讨论】:

您能否提供有关重现此问题的说明?如果是这样,这可能是向 Apple 报告的一个很好的错误报告。 我认为这是我明天的下一步,试图将其提炼成一个非常小的项目。我希望其他人也遇到过这种情况,并且有一个简单的解决方案或其他我不知道的方法。 如果不复制,我无法分辨,但你的描述和屏幕截图只是对我尖叫“错误”。 :) 您是否尝试过通常的故障排除步骤?按照增加麻烦的顺序:重新启动 Xcode、清理构建、清除派生数据。 我做了所有这些事情,@Alexander。唉,运气不好。 【参考方案1】:

看来我在 Xcode 11 中发现了一个错误。正如上面 UPDATE 中所述,它很容易重现。我已经向 Apple 提交了这个错误。

我现在仍在寻找解决方法,因为我使用了很多包含 Date 变量的结构。如果有人能找到,请在下方评论。

【讨论】:

可能与这个问题相同的错误:***.com/questions/58155061/… 在那个问题中,情况完全不同,但我们在调试器中再次显示了nil,而实际上不是@987654325完全是@。 刚刚发现了同样的错误。 ***.com/questions/58636312/… ...我正在调试并花了几个小时试图重新编写代码。我太相信调试器告诉我的东西了。它根本不是零...... Ughhhh @user1060500 很烦不是吗?我鼓励您向 Apple 报告它,并跟踪 bugs.swift.org/browse/SR-11593,这是 matt 下面提交的错误报告似乎已经登陆的地方。 这些报告的错误显示状态为已解决,但我在版本 11.2.1 (11B500) 上仍然遇到同样的错误,但更糟 在 XCode 12 中仍然面临这个问题【参考方案2】:

错误的原因不是 var start_time: Date? 存在或不存在,而是 Date 是 Swift Foundation 覆盖。如果您删除 Codable 一致性并将start_time 设置为NSDate?,一切都很好。很明显 LLDB 被 Date? 这样的 Swift 覆盖类型弄糊涂了。

在this linked question 中,我们看到与URL? 相同的问题。如果我们将其更改为 NSURL? 一切都很好。

我并不是说这是一个可行的解决方法!你想要并且需要使用 Swift 类型。我只是说这就是搞砸 LLDB 的原因。您可以在报告错误时包含该信息。

这个错误将在 Xcode 12.5 中修复。

【讨论】:

您可能希望将您的错误报告与我的相关联。我们需要他们来解决这个问题! 阿门,会的!一个小笔记——我发现它不一定是可选的。 哦不!我以为我测试得如此出色。 :( 哈!不,你做到了。感谢您也在那里发布大数据。他们会解决的。 我仍然在 XCode 11.1 和 10 月底看到这个问题。我可以做一个 po 并且它有效。

以上是关于实例化的可选变量在 Xcode 调试器中显示为 nil的主要内容,如果未能解决你的问题,请参考以下文章

Xcode 调试器显示不正确的变量值

Xcode 调试器不显示变量的值?

Xcode 11 中 Swift Combine.framework 的可选链接

按钮条件逻辑配置化的可选技术方案

swift中的可选类型

Terraform 中的可选变量在值为 null 时不会被忽略