NEW: My new book Pro SwiftUI is out now – level up your SwiftUI skills today! >>

Debugger variable questions

Forums > SwiftUI

I have had this problem on several other apps but this is the simplest one I have found.

struct ContentView: View {
  @State var z = ""
  var body: some View {
    VStack{
      Text ("z is: \(z)")
      Button("Show Sheet") {
        z = "Z"
        print("show \(z)")
      }
    }
  }
}

I set a break point at the start of the closure for button. If I use Step Over it does the z= and print. If I use step Into it goes back to the definition twice then comes back to the z=. In any case the bebugger shows self with a single element of z (SwiftUI.State< String >) wiht a value = (String) "" That does not change eventhough it prints show Z on the console. If I hit the button again it shows Z throughout.

I'm not real good with the debugger but I thought a v z would print the value of z but it says error: no variable named 'a' found in this frame not sure if that has anything to do with the problem but it is a second question I have. How do I print the contents of a variable?

It's really hard to debug when the debugger lies to me.

   

My problem is not with drawing the button. I have traced the creation of views and indeed there is a lot of jumping around and repeating sections.

My problem is when the user presses the button and the code in the closure is run. The debugger does not break during the creation of the view. The view shows up on the simulator and things are fine. I press the button in the simulator and the debugger breaks at the break point I set in the closure. Stepping over shows the z = and print. When the debugger stops at the print down in the variable area for the debuger I see self, and in that I see z, and under that I see value = (String) "". This is right after it did a z = "Z" so I would think z contains "Z" and not "". If I do another step show Z appears in the console. So, near as I can tell the variable z in self contained "" and print ("show (z)) printed show Z.

I got to this code trying to find a problem in some other, more complex code, where I set a value and the value was not thete later. This code is as simple as I can make it. I dedlare a variable, I change the value of the variable, I have the debugger active and in the statement after I set the new value I use the debugger to see what is in the variable.

Am I looking at the wrong, z in self, thing in the debugger, or do I have some other misunderstanding?

Another way of looking at it is I set a break at the print. When the debugger stops there I look at the z variable and the debugger shows a different value that what appears when I let the print go.

I made it simpler. Took out the VStack and Text items. The view now consists of one button. It still works the same way. Not quite.

If I run the full code the second time I press the button z contains "Z", but it I take out the Text the debugger shows "". Not sure why the presence of the Text view changes how the debugger sees stuff, but it does.

I still have the problem that the debugger does not show what I think is reality. At the print the debugger shows z has "" and using the variable gives "Z".

   

It likely has to do with the @State property wrapper. What we think of as just another property on a View doesn't actually work the same way as regular, non-@State properties.

Since, as @Obelix points out, View structs in SwiftUI are constantly being created and thrown away, the values you tag as @State are actually stored offsite somewhere else and merely observed and referenced inside the View. When the View struct is created again so it can be rerendered, the default value is ignored and the value stored outside the View struct is used instead.

Here's my attempt to explain what I think is probably going on:

  1. ContentView is created, with a default value of "" for @State var z
  2. Value of z is stored outside of the ContentView struct
  3. ContentView is rendered on screen, using value of z stored offsite
  4. ContentView struct is thrown away
  5. User clicks the Button
  6. Value of z (in the outside storage) is changed to "Z"
  7. ContentView struct is created, with a default value of "" for @State var z
  8. ContentView is rendered on screen, using value of z stored offsite
  9. breakpoint is hit
  10. @p7willm attempts to read z from the debugger
  11. debugger shows the value from the ContentView struct, not from the offsite storage
  12. execution continues
  13. ContentView struct is thrown away

You should try looking at z.wrappedValue in the debugger. Don't know if that will get you what you're looking for, but it's worth a try.

   

Ahh a bit closer. Back in the debugger I saw that what I had been calling z was actually _z. Expanding all the stuff I get 16 items that make up _z and none of them are the current value I put in z. There is only one string and that is the empty one. None of them are labeled WrappedValue

Now my problem might be how do I see the wrapped value for z?

Rather than the question of why does what I am doing produce this result the real question is

I am in the debugger, I am stopped on an instruction, how do I look at the current value of one of my @State variables? Hovering over the variable, definition or use, in the source does nothing. The only thing I see in the variable area of the debugger is self and if I expand that I see _z, if I expand that fully the only string I see is "", not what is currently there.

This should be easy. I have spent over an hour with Google and can not find any way to get the value of a @State variable in the debugger.

1      

Hacking with Swift is sponsored by Play

SPONSORED Play is the first native iOS design tool created for designers and engineers. You can install Play for iOS and iPad today and sign up to check out the Beta of our macOS app with SwiftUI code export. We're also hiring engineers!

Click to learn more about Play!

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.