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

我有一个inheritance自UIView的类SomeClass ,我想跟踪其方法setFrame:调用位置。

UIView情况下,我可以添加一个带有值的符号断点-[UIView setFrame:]但是我不能对我自己的类做同样的事情 – 它根本就不会在断点上调用/停止。 当然我不能使用-[UIView setFrame:]因为它会被多次调用。 如何解决这个问题?

我可以覆盖setFrame:在我自己的类中,但在这种情况下我不需要符号断点,而是使用通常的断点更好。 但在这种情况下,我还需要在我自己的课程中添加一些更改,这对我来说不太合适。

如果我理解正确,你想在 – [UIView setFrame:]上设置一个断点,但只有当“self”是SomeClass类的对象时它才会停止。 你可以用断点条件来做到这一点。 就像是:

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

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

使用特定队列调用dispatch_async时的符号断点

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

我在这里也有点过分夸大铸造。 我们没有许多这些函数的调试信息,因此您必须告诉调试器它们的返回类型是什么。

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

 (lldb) break set -S setFrame: 

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