【问题标题】:Accessing Class in a Breakpoint Conditional在断点条件下访问类
【发布时间】:2014-03-30 13:48:04
【问题描述】:

我有一个方法要调试:

-(void)doAThingWithObject:(BaseDataObject *)dataObject //called VERY often

我在这个方法中有一个 Xcode 断点,我只想在 BaseDataObject 的某个子类上中断,所以我添加了一个带条件的断点来检查该类:

[dataObject isKindOfClass:[SubClassOfBaseDataObject class]]

但是,这样做会导致解析错误!

Stopped due to an error evaluating condition of breakpoint 11.1: "[dataObject isKindOfClass:[SubClassOfBaseDataObject class]]"
Couldn't parse conditional expression:
error: no known method '+class'; cast the message send to the method's return type
error: 1 errors parsing expression

我已确保导入文件中的所有类,但调试器不知道我在条件中引用的类。

但是,在断点之前的方法内创建所述类的临时变量:

Class subClassCheck = [SubClassOfBaseDataObject class];

并更新断点条件以引用临时变量:

[dataObject isKindOfClass:subClassCheck]

不会引发错误。

在断点条件方面我有点新手,有人可以解释为什么我的第一种方法不起作用吗?

【问题讨论】:

    标签: ios objective-c xcode debugging xcode5


    【解决方案1】:

    调试基于 Cocoa 等大型框架的代码的一个复杂之处在于,编译器发出或调试器消耗您包含的整个框架闭包中的每个类型和函数是不切实际的。因此编译器使用一些启发式方法来减少生成的调试信息量。它只会为您实际使用的类型发出类型信息,以及定义该方法的函数/ObjC 方法信息(而不是在头文件中声明)。还有一个微妙之处,lldb 将从中读取方法的类型信息ObjC 运行时,虽然这些信息并不完整,因为它是为运行时而不是为调试器设计的......所以我们有时似乎知道有关 ObjC 方法违反先前规则的事情。

    另一个需要注意的重要事情是,返回大于指针的函数(如 NSMakeRect 等)的调用约定是这样的,如果调试器调用一个函数认为它返回一个指针并且它实际上返回一个更大的结构,该行为将导致程序中的堆栈损坏。如果你很幸运,当你继续时你会立即崩溃,但如果你不走运,它只会改变一些数据值并导致你花费数小时试图追踪实际上由调试器引起的一些有趣的行为。所以调试器会拒绝调用它不能确定返回类型的函数。

    无论如何,您得到的错误是因为调试器找不到您对象上“+class”方法的调试信息。这并不奇怪,因为“类”是 NSObject 上的一个方法,而不是你的类。我不确定为什么我们在运行时找不到它,也许是因为它是一个类方法?这值得一个错误。我们显然确实从运行时获得了 isKindOfClass: 的类型,否则您的解决方法也会失败。

    在这种情况下,由于您实际上知道类方法的返回类型,因此您可以通过在断点表达式中显式转换它来解决调试器缺乏知识的问题。在调试器的表达式解析器中强制返回函数有两个目的,一个是常规的 C 语言函数,另一个是告诉调试器一个函数的返回类型,否则它无法弄清楚。一种仅用于返回类型的简写原型。

    比如:

    [dataObject isKindOfClass: (Class) [SubClassOfBaseDataObject class]]
    

    无需更改代码即可工作。

    还要注意,断点条件的运行机制与“expr”或“print”命令相同。因此,试验断点命令最简单的方法是设置一个无条件断点,点击它,然后转到 lldb 控制台并使用“print”来玩弄,直到你得到一些有用的东西。

    【讨论】:

    • 这是迄今为止我在 StackOverflow 上收到的最令人满意的答案。它描述了我发现的东西,解释了我发现它的环境,甚至预先警告了我在处理调试器时可能会遇到的其他问题。我也很高兴我的期望(在某种程度上)是正确的,这是一个值得报告的错误发现。并在此期间获得一种解决方法,我可以直接加入吗?还能要求什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    • 2011-02-14
    • 2012-07-02
    • 2015-08-23
    • 1970-01-01
    • 2015-07-05
    相关资源
    最近更新 更多