32

自从我升级到 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,因为它可以被访问:

在此处输入图像描述

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

在此处输入图像描述

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

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

更新

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

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

然后将这些行添加到 application(_:didFinishLaunchingWithOptions:) 函数中:

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/吗?

4

2 回答 2

17

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

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

于 2019-09-28T16:05:18.227 回答
14

错误的原因不是var start_time: Date?存在或不存在,而是 Date 是 Swift Foundation 覆盖。如果您删除 Codable 一致性并制作start_timeNSDate?一切都很好。很明显 LLDB 被 Swift 覆盖类型(如Date?.

这个链接的问题中,我们看到了同样的问题URL?。如果我们将其更改为NSURL?一切都很好。

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

此错误计划在 Xcode 12.5 中修复。

于 2019-09-29T15:20:48.647 回答