Reputation: 10485
I am trying to improve my debugging skills, so started reading around here. I have the following piece of code:
var label = "tom"
self.label.text = label
print(label)
I have a break point in each of the lines, and in each of them I type
expression label = "jones"
po label
So, when I type po label
I get the expected result, which is jones
, but the text presented in the label and the console (from print(label)
) is tom
.
The tutorial I linked states that the changes should take effect for the entire run of the program. Is it false, or am I doing something wrong?
I am using Xcode Version 8.2.1 (8C1002) with an iPhone 7 Plus simulator.
Thanks!
Upvotes: 1
Views: 2204
Reputation: 27203
I'm not sure this helps, but what is going on is a little more complicated than you think.
Swift strings are actually structs, so if you stopped on the line before you assign to self.text.label
, and assign a new value to your label
var, you are actually changing the contents of the struct, which should by all rights mean that when you assign to self.text.label
from that struct, it really should pick up the new value...
The reason that doesn't work is that the swift compiler is smart about unboxing these structs so that it doesn't do unnecessary dereferences when possible. This happens even at -Onone
.
So for instance, in your example the swift compiled code has already unboxed the string and emitted code that directly references the contents. Changing the actual string contents doesn't change the references to the unboxed contents already in the assignment code, and so your change doesn't take.
You can see this IRL: if you make the compiler unable to know what the contents of the string are, it can't do this unboxing, and then you will see your debugger changes take effect.
Using this example code:
class HasLabel
{
var label : String = "Default Value"
}
func
main ()
{
var myLabel = HasLabel()
var string = "set in code"
string.removeSubrange(string.startIndex..<string.endIndex)
string.append("Different string in code")
myLabel.label = string // Set a breakpoint here
print ("Did it change? string: \"\(string)\" Label: \"\(myLabel.label)\"")
}
main()
in the debugger, I see:
(lldb) br s -p "Set a breakpoint here"
Breakpoint 1: where = tryme`tryme.main () -> () + 499 at tryme.swift:14, address = 0x0000000100001e93
(lldb) run
Process 8323 launched: '/private/tmp/tryme' (x86_64)
Process 8323 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100001e93 tryme`tryme.main () -> () at tryme.swift:14
11
12 string.removeSubrange(string.startIndex..<string.endIndex)
13 string.append("Different string in code")
-> 14 myLabel.label = string // Set a breakpoint here
^
15 print ("Did it change? string: \"\(string)\" Label: \"\(myLabel.label)\"")
16 }
17
(lldb) expr string = "Set in debugger"
(lldb) c
Process 8323 resuming
Did it change? string: "Set in debugger" Label: "Set in debugger"
Process 8323 exited with status = 0 (0x00000000)
There you see the debugger change actually took. But if you comment out the string.removeSubrange
and string.append
, then the change will no longer take.
Upvotes: 1