I have a class SomeClass
which is inherited from UIView
and I want to track where its method setFrame:
was called.
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?
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.
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
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:
Symbolic breakpoint for when dispatch_async is called with a specific queue
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.
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:
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..