Unable to use new constant value modified by expression command

My goal is to change value of let for debugging purposes. I'm able to set the breakpoint and evaluate new value, but this new value isn't used by print statement.


private extension UIAlertController {
    @objc func textDidChange() {
        guard let firstTextField = textFields?.first,
            let name = firstTextField.text, name != "" else { return }
        let normalizedString = name.capitalizingFirstLetter().pascalCasedStringForSeparator("-")
        print("----")
        print("name is \(normalizedString)")
    }
}


I have a breakpoint for the line #06 just before the last print statement.

Next step is to verify current value for the name. It's "Hfg". So far so good.

Next step is to set new value by invoking e normalizedString = "!!!!!" command.

My expectation is the last print statement should print "name is !!!!!" instead of "name is Hfg" but it's not.


Terminal output is:

(lldb) e normalizedString
(String) $R4 = "Hfg"
(lldb) e normalizedString = "!!!!!"
(lldb) e normalizedString
(String) $R8 = "!!!!!"
----
name is Hfg
(lldb) e $R4
(String) $R10 = "Hfg"
(lldb) e $R8
(String) $R12 = "!!!!!"
(lldb)


Variables view window display the new value for the normalizedString but print command doesn't use that value.

How can I force the App to actually use that new value for print command, what I'm missing here?


Replies

Screenshot describing the problem: https://i.ibb.co/CwwMjys/Debugger.png

Modifying variables in the debugger has always been a tricky proposition and you’re dealing with a particularly thorny case here because the Swift compiler has deep assumptions that

let
values won’t change, especially in a context like this where the compiler can ‘see’ all references to the constant.

To understand what’s actually going on here you’d have to disassemble the code, and that’s a lot of work. Which raises an important question: Are you just trying to solve the problem in this specific case? Or is this just one specific example of a problem you’re trying to solve in general?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

This is just one specific example of a problem I'm trying to solve in general. I've tried to change let to var but looks like compiler still uses some kind of optimizations and value wasn't changed during debugging process:


    @IBAction func didTouchButton(_ sender: UIButton) {
        var input = foo()
        print("Text is: \(input)")
    }
    
    func foo() -> String {
        var text = "some text"
        return text
    }


Trying to modify text value by using breakpoint at line #08 doesn't cause changing actual returned value.

Even more, debugging similar Objective-C code works like a charm. Here is an example:


- (IBAction)didTouchButton:(UIButton *)sender {
    NSString *input = [self foo];
    NSLog(@"Text is %@", input);
}

- (NSString *)foo {
    NSString *text = @"some text";
    return text;
}


and the output is:


(lldb) e text = @"new text"
(NSTaggedPointerString *) $1 = 0xd5c9f7cee1f707ae @"new text"
2018-12-08 10:32:53.632241+0200 DebugTest[2433:34439] Text is new text


P.S. I'm using Xcode 10.0 and 10.1. I do understand in objc we are dealing with pointer to the object and Swift's String is a struct...

This is just one specific example of a problem I'm trying to solve in general.

I don’t think there’s a solution to this in the general case, other than for the compiler and debugger to change to do a better job of this. Please do file a bug report about this, then post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks, bug #46591779 was raised.