调试器在Xcode中的“p”和“po”命令?

时间:2015-03-02 09:33:27

标签: objective-c xcode debugging console lldb

实施例。我在旧项目中编写了以下字符串,并使用了一个新的,明确的字符串:

UIInterfaceOrientation k = [UIApplication sharedApplication].statusBarOrientation;

明确项目的控制台输入输出:

(lldb) po k
UIInterfaceOrientationLandscapeLeft

如果我写“po k” - 一个无用的整数列表,那么在我的旧项目中有些糟糕。

此外,我无法在新项目中打印大多数对象。

9 个答案:

答案 0 :(得分:11)

我不知道你的情况发生了什么,但只是让人们清楚po& p

p命令(又名expr --)获取它给出的参数,将它们编译为好像它们是在当前帧的上下文中编写的源代码表达式,执行结果 - 通过如果可能的话,在编译结果上运行解释器,或者通过JITing编译结果,将其插入目标程序,然后在那里运行它。然后打印评估结果。

po命令(又名expr --O --)执行p所做的一切,但是如果结果是指向ObjC对象的指针,则不是打印结果,而是调用该对象& #39; s"描述"方法,并打印该方法返回的字符串(*)。同样,如果结果是CF对象,它将调用CFShow并打印结果。如果这两个尝试都失败了,它将继续并按p打印结果。

所以po大部分都像p。但是如果你对它不是实际对象的东西使用po,你可能会得到一些奇怪的结果。例如,ObjC有一个优化(标记指针),它表示对象指针中某些对象(例如NSNumbers)的内容。没有"真实"对象,只是煮熟的指针。因此,如果您尝试将po一个恰好看起来像标记指针的整数,您将获得一些可能不相关的ObjC对象的描述,而不是整数的值。

当然,po正在做更多的工作,所以除非你真的想要一些对象的描述,否则p会更有效率。

  • 实际上,它调用debugDescription(如果存在的话),并且如果它没有...则回溯到描述

答案 1 :(得分:10)

p = print

po =打印对象

p打印原始变量的值或引用的值

po尝试为该对象调用-description并打印返回的字符串

答案 2 :(得分:1)

  • 使用po,p和v打印变量
    • po最终编译并执行两次,一次评估表达式,再一次获取对象描述。
    • v完全不编译:无法评估任何表达式,但允许属性访问,并且可以进行递归动态类型解析,因此将每个属性都视为实际的运行时类型。

enter image description here

对于有兴趣了解更多信息的人:https://developer.apple.com/videos/play/wwdc2019/429/

将其添加为可见性的答案,并解释每个调试命令的功能

答案 3 :(得分:1)

po尝试将要打印的内容作为对象。在许多情况下,它与p类似,但是在某些情况下会出现差异。

了解差异的最简单方法是:比较p 0po 0的输出。

(lldb) p 0
  (int) $26 = 0
(lldb) po 0
  <nil>

答案 4 :(得分:0)

UIInterfaceOrientation不是(Objective-C)对象,而是整数(enum:NSInteger)。您根本不应使用po(打印对象)。

答案 5 :(得分:0)

Strip debug symbols during copy

在大多数答案中,他们建议将优化设置为“none”,但忘记将此选项设置为NO(至少对于调试配置)。

答案 6 :(得分:0)

似乎区别在于lldb / gdb调试器。 iOS项目使调试器更可行的唯一方法是expr @import UIKit。但它可能不适用于较旧的xcode版本...并且您需要在每次重新启动后在控制台中输入此字符串。自动化它的唯一方法是使用此表达式的额外断点。

答案 7 :(得分:0)

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

答案 8 :(得分:-1)

这是参考Jim Ingham所说的。输入&#34; p&#34;而不是&#34; po&#34;。当我这样做时,Xcode显示正确的信息。试试吧。