Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
904 views
in Technique[技术] by (71.8m points)

ios - Using of symbolic breakpoints for child classes in Xcode?

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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..


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...