我正在尝试跟踪我的UITabBar(子类为ASTabBar)帧/边界的代码。我正在使用this post来指导我,以便我可以在lldb调试器中设置一个Watchpoint。
我在我的UITabBarController中实现了一个名为- (void)viewWillLayoutSubviews
的方法,并在那里设置一个断点来添加我的Watchpoint。
到目前为止,我已完成以下工作:
(lldb) po self.tabBar
<ASTabBar: 0x7fd814606fc0; baseClass = UITabBar; frame = (0 574; 375 49); autoresize = W+TM; layer = <CALayer: 0x7fd814607690>>
(lldb) break set -F '-[CALayer setBounds:]' -c '((int*)$esp)[1] == 0x7fd814607690'
Breakpoint 26: where = QuartzCore`-[CALayer setBounds:], address = 0x000000010fd4e371
Stopped due to an error evaluating condition of breakpoint 26.1: "((int*)$esp)[1] == 0x7fd814607690"
Couldn't execute expression:
Supposed to interpret, but failed: Interpreter couldn't read from memory
我的问题是,在调用此方法后的某个时刻,我的UITabBar的高度已从49.f
更改为44.f
。我想找到对此负责的内容。
我认为引用((int*)$esp)[1]
对我的实现是错误的。我不确定[1]
在我在链接中关注的示例中指的是什么。显然它是内存偏移量的索引,但我不确定它的值应该是引用图层的帧。我的猜测是,它类似于调试器在打印出(调试器中的po
)视图属性时输出详细信息列表的方式。 Ordered:ASTabBar(内存中对象的开头),baseClass,frame,autoresize和layer但是,例如将索引值更改为[2]
不会给我一个不同的输出,也不会将它设置为[0]
或者完全省略这个指数......
最后,我认为在显示视图之前我的方法- (void)viewWillLayoutSubviews
被调用两次是很奇怪的。这是第二次调用这个方法,我注意到TabBar的高度现在是44.f
。
答案 0 :(得分:0)
“self”是传递给ObjC方法调用的第一个参数,并且您尝试将断点限制为仅此对象为“self”的情况。所以你想要的条件是“函数的第一个参数==一些指针值”。
由于您的地址显然是64位地址,因此您可能正在调试64位Intel程序。在32位Intel ABI中,参数在堆栈上传递。 $ esp是堆栈指针,因此您所遵循的示例是在堆栈指针之后抓取第二个int。这适用于32位英特尔。
但对于64位Intel,前几个参数都在寄存器中传递。所以你需要弄清楚哪个寄存器用于传递第一个参数。但是,对于在寄存器中传递参数的体系结构,lldb创建了便利别名变量:$ arg1,$ arg2等,它指向ABI为传递这些参数指定的任何内容。所以条件:
$arg1 == 0x7fd814606fc0
应该意味着只有在将对象传递给setBounds时断点才会停止。这种情况适用于64位Intel&amp; 32位和64位ARM程序。