在 Xcode 中使用子 类 的符号断点?

Using of symbolic breakpoints for child classes in Xcode?

我有一个继承自 UIView 的 class SomeClass,我想跟踪调用它的方法 setFrame: 的位置。

UIView 的情况下,我可以添加一个值为 -[UIView setFrame:] 的符号断点,但我不能为我自己的 class 做同样的事情 - 它永远不会 called/stopped 在断点上。当然我不能使用 -[UIView setFrame:] 因为它会被调用额外的时间。如何解决这个问题?

我可以在我自己的 class 中覆盖 setFrame: 但在这种情况下我不需要符号断点,最好使用通常的断点。但是在这种情况下我也需要自己添加一些改动class对我来说不是很合适

如果我理解正确,您想在 -[UIView setFrame:] 上放置断点,但仅当 "self" 是 class SomeClass 的对象时才停止。您可以使用断点条件来做到这一点。类似于:

(int) strcmp("SomeClass", (const char *)class_getName((id)[(id) $arg1 class])) == 0

这里唯一的技巧是 $arg1 是保存第一个参数的寄存器的别名,在 ObjC 方法中第一个参数总是 self。请注意,$arg1 寄存器别名仅针对使用寄存器进行参数传递的体系结构定义;特别是 32 位 x86 不会以这种方式传递参数。以下答案很好地描述了如何在大多数常见架构上获得第一个参数:

Symbolic breakpoint for when dispatch_async is called with a specific queue

这可能会稍微减慢您的进程,因为它会在每次调用 [UIView setFrame] 时停止,但没有好的方法可以避免这种情况,除非您建议覆盖 setFrame: 然后停在那里。

我在这里也有点令人讨厌地过度铸造。我们没有其中许多函数的调试信息,因此您必须告诉调试器它们的 return 类型是什么。

顺便说一下,lldb 命令行也有一个 "break on selector" 类型,它会在给定选择器的所有实现上中断。没有 UI 调用它的方法,但在控制台中你可以这样做:

(lldb) break set -S setFrame:

因此您可以在所有 setFrame: 方法上设置一个断点,然后添加相同的条件(您可以通过将 -c 标志传递给 break set 命令来完成此操作。如果此断点结束up 匹配太多函数,您可以通过使用 break list 查找它们的索引来禁用单个命中,然后使用您将在 break list 输出中看到的 bkpt.loc 形式逐一禁用它们..