打印属性

时间:2016-01-04 10:41:44

标签: objective-c xcode lldb

在我尝试打印Objective C属性时遇到大问题,我几乎肯定确定应该工作。

考虑以下设置:

Case setup

视图控制器的属性严格设置了类( Card * ),但仍然,LLDB输出解析错误,其中在类型的对象上找不到子属性id

在视图控制器上定义对象属性(参见第5和第6点):

  1. 停在控制器代码内的断点处(f.e. in -viewDidAppear:method)
  2. 尝试使用po _card(第1点和第2点)
  3. 打印出该属性
  4. 尝试使用po _card.offlineURL打印出子属性(第3点和第4点)
  5. 发生LLDB解析错误
  6. 通过[_card offlineURL]打印输出正确的对象描述,因为LLDB向Card对象发送消息而没有进行类检查。

    控制器上对象属性的定义虽然声明了非id类,但是(第5点)。

    我希望LLDB打印出属性对象的子属性描述,在这种情况下包含URL字符串的NSString,但是会发生这种恼人的LLDB错误。

    这只是许多人的一个例子。有时它会影响直接属性打印输出,数字打印等。自从Swift开始集成以来,这些问题变得更加频繁,自6.2以来每个新版本的Xcode都更糟糕,包括最新的7.2。

    在许多情况下,我的Objective C项目会发生这种情况,但有时它在不同情况下也能正常工作。

    您是否了解此问题的解决方法或修复方法?我已经就Apple Bug Reporter提交了一份报告,但这肯定需要时间让Apple注意到。

1 个答案:

答案 0 :(得分:1)

在您的问题中给出信息的最可能的问题是我们实际上没有_card的调试信息。

lldb命令:

(lldb) image lookup -t Card

会告诉你lldb是否有可用的Card调试信息。如果没有找到任何内容,那么项目的某些部分可能没有使用调试信息构建。如果该命令确实找到了一些正确的Card定义,则必须是_card ivar的调试信息没有正确地连接到这种类型。

如果有卡的定义,则解决方法:

(lldb) po ((Card *) _card).offLineURL

可用。

为了将来参考,还有另外两个行为可能会使您试图找出这里发生的事情变得复杂:

1)(w.r.t.图3)Xcode IDE在调试窗口和源代码编辑器中使用其内置索引器进行自动完成。但调试器运行调试信息,因为我们需要能够调试非Xcode内置的东西。因此,自动完成可以在表达式中找到名称这一事实并不能告诉您有关lldb将做什么的任何信息。

2)(w.r.t. picture 2)po强制将你试图“po”的表达式转换为ObjC对象(即“id”),然后调用其描述方法。不覆盖描述的ObjC对象的描述方法打印类型名称和地址。所以lldb不需要知道_card ivar的类型来获得你看到的输出。当表达式更复杂时,我们才开始需要类型,并涉及访问表达式中的ivar或ObjC对象的属性。

另请注意,默认情况下:

(lldb) print _card

lldb将评估表达式“_card”,找到它解析为至少类型为id的指针,然后跟随该指针的isa指针进入ObjC运行时以找出动态类型是什么。因此在这种情况下可能会打印Card *

但是表达式解析器尚未被教导在解析中解析表达式解析器中的动态类型的子表达式。这实际上是一个很大的伎俩...所以如果它不知道_card的完整类型,那么:

(lldb) print _card.offlineURL

不起作用,因为id确实没有该名称的属性。

您可以通过以下方式解决此问题:

(lldb) print _card
$0 = (Card *) 0x12345678

然后:

(lldb) print $0.offlineURL

因为结果变量捕获完整的动态类型信息,所以后续表达式中也可以使用该信息。