实例化的可选变量在 Xcode 调试器中显示为 nil
Instantiated optional variable shows as nil in Xcode debugger
自从我升级到Xcode 11和Swift 5.1后,我遇到了一个奇怪的问题--可选变量实例化后,它仍然可以在[=73中显示为nil =]调试器!
我有一个可选的 class 变量,名为 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 中的构建模式是否没有设置其 "Debug executable" 标志。但确实如此。我什至在关闭和打开标志的情况下清理并重建了项目以确保。
无论是在变量视图中查看 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")")
像之前一样设置断点,当 运行ning 时,请注意调试器即使在分配后仍将 booking 显示为 nil,就像我原来的情况一样。
然后注释掉 start_time
变量,重新 运行,注意现在调试器显示 booking
在之后有一个值被分配,正如人们所期望的那样。
因此,在这样的结构中,日期变量(可选与否)似乎会使调试变得混乱。特别是日期变量——将变量更改为其他类型,如 Int、Int?、String、String?……没有问题。
除非我遗漏了一些非常基本的东西,否则这对我来说似乎是 Xcode 调试器中的一个错误。如果是这样,最好的报告方式是 https://developer.apple.com/bug-reporting/?
看来我在 Xcode 11 中发现了一个错误。它很容易重现,如上面 UPDATE 中所述。我已经向 Apple 提交了错误。
我现在仍在寻找解决方法,因为我使用了很多包含 Date 变量的结构。如果有人能找到一个,请在下面发表评论。
错误的原因不是 var start_time: Date?
存在或不存在,而是 Date 是 Swift Foundation 覆盖。如果您删除 Codable 一致性并使 start_time
成为 NSDate?
,一切都很好。很明显 LLDB 被 Swift 覆盖类型混淆了,比如 Date?
.
在 中,我们在 URL?
中看到了同样的问题。如果我们将其更改为 NSURL?
一切都很好。
我并不是说这是一个可行的解决方法!您想要并且需要使用 Swift 类型。我只是说这就是搞乱 LLDB 的原因。您可以在报告错误时包含该信息。
此错误将在 Xcode 12.5 中修复。
自从我升级到Xcode 11和Swift 5.1后,我遇到了一个奇怪的问题--可选变量实例化后,它仍然可以在[=73中显示为nil =]调试器!
我有一个可选的 class 变量,名为 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 中的构建模式是否没有设置其 "Debug executable" 标志。但确实如此。我什至在关闭和打开标志的情况下清理并重建了项目以确保。
无论是在变量视图中查看 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")")
像之前一样设置断点,当 运行ning 时,请注意调试器即使在分配后仍将 booking 显示为 nil,就像我原来的情况一样。
然后注释掉 start_time
变量,重新 运行,注意现在调试器显示 booking
在之后有一个值被分配,正如人们所期望的那样。
因此,在这样的结构中,日期变量(可选与否)似乎会使调试变得混乱。特别是日期变量——将变量更改为其他类型,如 Int、Int?、String、String?……没有问题。
除非我遗漏了一些非常基本的东西,否则这对我来说似乎是 Xcode 调试器中的一个错误。如果是这样,最好的报告方式是 https://developer.apple.com/bug-reporting/?
看来我在 Xcode 11 中发现了一个错误。它很容易重现,如上面 UPDATE 中所述。我已经向 Apple 提交了错误。
我现在仍在寻找解决方法,因为我使用了很多包含 Date 变量的结构。如果有人能找到一个,请在下面发表评论。
错误的原因不是 var start_time: Date?
存在或不存在,而是 Date 是 Swift Foundation 覆盖。如果您删除 Codable 一致性并使 start_time
成为 NSDate?
,一切都很好。很明显 LLDB 被 Swift 覆盖类型混淆了,比如 Date?
.
在 URL?
中看到了同样的问题。如果我们将其更改为 NSURL?
一切都很好。
我并不是说这是一个可行的解决方法!您想要并且需要使用 Swift 类型。我只是说这就是搞乱 LLDB 的原因。您可以在报告错误时包含该信息。
此错误将在 Xcode 12.5 中修复。