What's the difference between “p” and “po” in Xcode's LLDB debugger?

后端 未结 9 1452
无人及你
无人及你 2021-02-04 12:27

Example. I write the following string in my old project and a new, clear one:

UIInterfaceOrientation k = [UIApplication sharedApplication].statusBarOrientation;
         


        
相关标签:
9条回答
  • 2021-02-04 12:42

    This is in reference to what Jim Ingham said. Type "p " instead of "po ". When I do that Xcode displays the correct information. Try that.

    0 讨论(0)
  • 2021-02-04 12:46

    po tries to treat what you want to print, as an object. In many cases it is similar to p, but there are cases where the difference emerges.

    The simplest way to see the difference: compare the output of p 0 and po 0.

    (lldb) p 0
      (int) $26 = 0
    (lldb) po 0
      <nil>
    
    0 讨论(0)
  • 2021-02-04 12:47

    UIInterfaceOrientation is no (Objective-C) object, but an integer (enum:NSInteger). You should not use po (print object) at all.

    0 讨论(0)
  • 2021-02-04 12:49
    p prints value of primitive variable or value of a reference
    po try to call -description for that object and print returned string
    
    There is also **v command** in lldb. Explaining using example.
    
    protocol Activity {} 
    struct Trip: Activity { 
    var name: String 
    var destinations: [String] 
    } 
    let cruise: Activity = Trip(...)
    
    Using v command 
    (lldb) v cruise.name
    (string) cruise.name = "print name"
    //As it uses dynamic resolution
    
    Using p command
    (lldb) p cruise.name
    //execution interrupted
    
    0 讨论(0)
  • 2021-02-04 12:51

    p = print

    po = print object

    p prints value of primitive variable or value of a reference

    po try to call -description for that object and print returned string

    0 讨论(0)
  • 2021-02-04 12:59

    I don't know what is going on in your case, but just so folks are clear on the difference between po & p:

    The p command (a.k.a. expr --) takes the arguments it is given, compiles them as though they were a source code expression written in the context of the current frame, executes the result - either by running an interpreter on the result of the compilation if that is possible, or by JITing the result of the compilation, inserting it into the target program, and running it there. Then it prints the result of the evaluation.

    The po command (a.k.a. expr --O --) does everything that p does, but instead of printing the result, if the result is a pointer to an ObjC object, it calls that object's "description" method, and prints the string returned by that method(*). Similarly, if the result is a CF object, it will call CFShow and print the result of that. If both these attempts fail, it will go ahead and print the result as p would have.

    So po is mostly like p. But you can get some weird results if you use po on things that it aren't actually objects. For instance, ObjC has a optimization (tagged pointers) that represent the contents of some objects (e.g. NSNumbers) in the object pointer. There isn't a "real" object, just a cooked pointer. So if you try to po an integer that just happens to look like a tagged pointer, you'll get the description of some probably unrelated ObjC object, not the value of the integer.

    And of course, po is doing a lot more work, so unless you really want some object's description of itself, p is more efficient.

    • Actually, it calls debugDescription, if that exists, and falls back to description if it doesn't...
    0 讨论(0)
提交回复
热议问题