我有一个继承自SomeClass
的课程UIView
,我想跟踪调用方法setFrame:
的位置。
在UIView
的情况下,我可以添加一个带有值-[UIView setFrame:]
的符号断点,但我不能对我自己的类做同样的事情 - 它根本就不会在断点上调用/停止。当然我不能使用-[UIView setFrame:]
,因为它会被称为额外的时间。如何解决这个问题?
我可以在我自己的类中覆盖setFrame:
但在这种情况下我不需要符号断点,而是使用通常的断点更好。但在这种情况下,我还需要在我自己的课程中添加一些更改,这对我来说不太合适。
答案 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
表单逐个禁用它们。