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

时间:2015-07-14 10:11:59

标签: ios objective-c xcode debugging uiview

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

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

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

1 个答案:

答案 0 :(得分:2)

如果我理解正确,你想在 - [UIView setFrame:]上设置一个断点,但只有当“self”是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,否则没有好办法避免这种情况:然后停在那里。

我也有点讨厌过度施法。我们没有许多这些函数的调试信息,因此您必须告诉调试器它们的返回类型是什么。

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

(lldb) break set -S setFrame:

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