Since I upgraded to Xcode 11 and Swift 5.1 I've encountered a strange issue -- after an optional variable is instantiated, it can still show as up nil in the Xcode debugger!
I have an optional class variable called booking
:
var booking: Booking?
It's of type Booking
:
public struct Booking: Codable {
var id: Int?
var start_time: Date?
var payment_currency: String = "USD"
var payment_amount: Int?
}
When I'm stepping through the code, I can see booking
before it's allocated... It's nil, great:
Then after it's allocated... What, still nil??:
I wondered if it was being treated like a lazy variable somehow. But it's not really nil, because it can be accessed:
After searching for a while, I wondered if my build schema in Xcode didn't have its "Debug executable" flag set. But it does. I even cleaned and rebuilt the project with the flag off and on to be sure.
Whether I view booking
in the Variables View or enter p booking
in the Console View, it shows up as nil.
What's going on here? I need the predictability of debugging I had before this upgrade.
UPDATE
I distilled a simple way to reproduce the issue. First, create an empty single-view project and add this to the top of AppDelegate.swift:
public struct Booking: Codable {
var start_time: Date?
var payment_currency: String = "USD"
}
Then add these lines to the application(_:didFinishLaunchingWithOptions:) func:
booking = Booking()
print("booking.payment_currency = \(booking?.payment_currency ?? "NULL")")
Set a breakpoint as before and when running, notice that the debugger shows booking as nil even after being assigned, as in my original case.
Then comment out the start_time
variable, re-run, and notice that now the debugger shows booking
having a value after being assigned, as one would expect.
So it seems that Date variables, optional or not, in a struct like this make debugging confusing. Specifically Date variables -- change the variable to other types like Int, Int?, String, String?... and there's no issue.
Unless I'm missing something very basic, this seems like a bug in the Xcode debugger to me. If so, would the best way to report it be at https://developer.apple.com/bug-reporting/?
When you run an application in Xcode, the debugger is automatically started and attached to the process of the application. Click the Run button in the top left or press Command + R. From the moment the application is up and running, we can start inspecting the process and, if necessary, debug it.
Swift is tightly coupled to the version of the Swift compiler embedded in the debugger. Tight integration of compiler and debugger enables accurate inspection of Swift types as well as full-featured expression evaluation in the context of a rapidly evolving language.
It appears I've found a bug in Xcode 11. It's easily reproducible as outlined in the UPDATE above. I've filed the bug with Apple.
I'm still looking for a workaround now, since I use quite a few structs containing Date variables. If anybody can find one, please comment below.
The cause of the bug is not that var start_time: Date?
is present or absent, but that Date is a Swift Foundation overlay. If you remove the Codable conformance and make start_time
an NSDate?
, everything is fine. So clearly LLDB gets confused by Swift overlay types like Date?
.
In this linked question, we see the same issue with URL?
. If we change it to NSURL?
everything is fine.
I'm not saying that that's a viable workaround! You want and need to use Swift types. I'm just saying that this is what is messing up LLDB. You can include that info when you report the bug.
This bug is slated to be fixed in Xcode 12.5.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With