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

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在它被分配之前... 它是空的,太好了:

enter image description here

然后,在它被分配之后... 等等,还是空的吗??:

enter image description here

我想知道它是否像一个懒变量一样被处理。 但它并不真正为空,因为它可以被访问:

enter image description here

寻找了一段时间之后,我想知道Xcode中的构建模式是否没有设置其“调试可执行文件”标志。 但是它确实有。 我甚至关闭和打开标志来清理和重建项目,以确保。

enter image description here

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

这里发生了什么? 我需要升级前具有的调试预测性。

更新

我简化了一个复现此问题的简单方法。 首先,创建一个空的单视图项目,并将其添加到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")")

像之前一样设置断点并运行,注意到调试器显示booking为nil,即使已被赋值,就像我原来的情况一样。

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

因此,似乎结构体中的Date变量(无论是否可选)使调试变得混乱。具体来说,只要将变量更改为其他类型,例如Int、Int?、String或String?等等,就不会出现问题。

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


1
你能提供重现这个问题的指导吗?如果可以,那么向苹果提交一个好的错误报告。 - matt
我认为明天我的下一步是将其浓缩成一个非常小的项目。我希望有人遇到过这个问题,并且有一个简单的解决方案或其他我不知道的东西。 - Dylan
1
我无法确定问题是否存在,但是你的描述和截图让我感觉这很可能是一个“bug”。 :) - matt
干得好,做得好! - matt
为此苦苦挣扎了数小时,创建了测试用例等,直到找到这篇文章。问题仍然存在,但解决方法是使用NSDate而不是Date。即使日期不是可选的,问题绝对是日期。 - C6Silver
显示剩余5条评论
2个回答

17

看起来我在Xcode 11中发现了一个bug。如上面的更新所述,这很容易被复制。我已经向Apple报告了这个问题。

现在我正在寻找解决方法,因为我使用了相当多的包含日期变量的结构体。如果有人能找到一种解决方法,请在下面评论。


2
可能是与此问题相同的错误:https://dev59.com/nVMH5IYBdhLWcg3w0DS9 在那个问题中,情况完全不同,但是我们再次在调试器中看到了nil,而实际上这个东西根本不是nil - matt
1
刚刚发现了同样的 bug。https://stackoverflow.com/questions/58636312/decoder-decode-setting-valid-iso8601-date-as-nil/58653084#58653084 ... 我一直在调试并花了几个小时尝试重新编写代码。我太过于相信调试器告诉我的东西了。它根本不是 nil... 唉 - user1060500
@user1060500 很烦人,不是吗?我鼓励你向苹果报告此问题,并跟踪https://bugs.swift.org/browse/SR-11593,这是Matt提交的错误报告似乎已经落实的地方。 - Dylan
这些报告的漏洞显示为已解决状态,但我使用的是版本11.2.1(11B500),仍然遇到相同的漏洞,甚至更严重。 - Ron Srebro
目前这个问题仍然没有解决:https://bugs.swift.org/browse/SR-11593。不确定这些问题何时会被解决并纳入Xcode中。似乎我们只能在每个版本发布后直接向苹果报告此问题。我发现这仍然是开发的障碍。 - Dylan
1
在XCode 12中仍然遇到此问题。 - touti

14
错误的原因并不在于是否存在var start_time: Date?,而是因为Date是Swift Foundation覆盖层。如果删除Codable一致性并使start_time成为NSDate?,则一切正常。因此,很明显LLDB会对像Date?这样的Swift覆盖类型感到困惑。
此链接的问题中,我们看到了同样的问题出现在URL?上。如果将它更改为NSURL?,则一切正常。
我并不是说这是一个可行的解决方法!你需要使用Swift类型。我只是想说这正是搞乱LLDB的东西。当你报告错误时,可以包含这些信息。 这个bug计划在Xcode 12.5中修复。

你可能想把你的错误报告和我的联系起来。我们需要它们来修复这个问题! - matt
好的,我会做!只要提一点小建议 -- 我发现它不必是可选项。 - Dylan
哈!不,是你发了。谢谢你也发布了这个重要信息。他们会解决的。 - Dylan
XCode11.2.1,这个bug仍然存在,浪费了我一整天的时间... - Jungen yan
po LLDB 命令不会受到这个问题的影响,你应该使用它来代替 print。 - Vlad
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接