在Xcode中为子类使用符号断点?
我有一个类 SomeClass
,它继承自 UIView
,我想跟踪它的方法 setFrame:
被调用。
I have a class SomeClass
which is inherited from UIView
and I want to track where its method setFrame:
was called.
如果 UIView
我可以添加值为的符号断点 - [UIView setFrame:]
但是我不能为自己的类做同样的事情 - 它在断点上根本就不会被调用/停止。当然,我不能使用 - [UIView setFrame:]
,因为它将被称为额外的时间。如何解决这个问题?
In case of UIView
I could add a symbolic breakpoint with value -[UIView setFrame:]
but I can't do the same for my own class - it is simply never called/stopped on a breakpoint. And of course I can't use -[UIView setFrame:]
because it will be called extra times. How to solve this issue?
我可以在我自己的课程中覆盖 setFrame:
,但在这种情况下我不会t需要符号断点,更好地使用通常的断点。但是在这种情况下,我还需要在我自己的类中添加一些更改,这对我来说不是很合适。
I could override setFrame:
in my own class but in this case I don't need symbolic breakpoint and it's better to use usual breakpoint instead. But in this case I also need to add some changes in my own class and it is not very appropriate for me.
我正确理解,你想在 - [UIView setFrame:]上放置一个断点,但只有当self是SomeClass类的对象时才会停止。你可以用断点条件来做到这一点。一些东西:
If I understand correctly, you want to put a breakpoint on -[UIView setFrame:] but only have it stop when "self" is an object of class SomeClass. You can do that with a breakpoint condition. Something like:
(int) strcmp("SomeClass", (const char *)class_getName((id)[(id) $arg1 class])) == 0
这里唯一的窍门是 $ arg1
是保存第一个参数的寄存器的别名,而在ObjC方法中,第一个参数始终为 self
。注意,$ arg1寄存器别名仅针对使用寄存器进行参数传递的体系结构定义;特别是32位x86不会以这种方式传递参数。以下答案有一个很好的描述如何获得最常见架构的第一个参数:
The only trick here is that $arg1
is an alias for the register that holds the first argument, and in ObjC methods the first argument is always self
. Note, the $arg1 register alias is only defined for architectures that use registers for argument passing; in particular 32-bit x86 does not pass arguments this way. The following answer has a good description of how to get the first argument on most common architectures:
这可能会减慢您的进程,因为它会在每次调用 [UIView setFrame]
时停止,但没有好的方法避免你,除非你建议覆盖setFrame:然后在那里停止。
This may slow down your process a bit, since it will stop at every call to [UIView setFrame]
but there's no good way to avoid that except as you suggest to override setFrame: and then stop there.
我也有点厌恶地超过这里的投射。我们没有许多这些功能的调试信息,所以你必须告诉调试器他们的返回类型是什么。
I am also a bit obnoxiously overdoing the casting here. We don't have debug information for many of these functions, so you have to tell the debugger what their return types are.
顺便说一句,lldb命令行也有一个中断选择器类型,这将破坏给定选择器的所有实现。没有UI方法来调用它,但是在控制台中可以执行以下操作:
By the way, the lldb command line also has a "break on selector" type which will break on all implementations of a given selector. There's no UI way to call this up, but in the console you can do:
(lldb) break set -S setFrame:
所以你可以在所有setFrame:方法上设置一个断点,然后添加相同的条件通过将 -c
标志传递给 break set
命令来执行此操作,如果此断点最终匹配太多功能,您可以通过使用 break list
查找其索引来禁用单个命中,然后使用 bkpt.loc
c>表格,您将在中断列表中看到
output ..
So you could set a breakpoint on ALL setFrame: methods, and then add the same condition (you can do this by passing the -c
flag to the break set
command. If this breakpoint ends up matching too many functions, you can disable individual hits by looking up their indices with break list
and then disabling them one by one by using the bkpt.loc
form you'll see in the break list
output..