【问题标题】:Using of symbolic breakpoints for child classes in Xcode?在 Xcode 中对子类使用符号断点?
【发布时间】:2015-07-14 10:11:58
【问题描述】:

我有一个类 SomeClass,它继承自 UIView,我想跟踪它的方法 setFrame: 的调用位置。

UIView 的情况下,我可以添加一个值为-[UIView setFrame:] 的符号断点,但我不能为我自己的类做同样的事情——它根本不会在断点上调用/停止。当然我不能使用-[UIView setFrame:],因为它会被额外调用。如何解决这个问题?

我可以在我自己的类中覆盖setFrame:,但在这种情况下我不需要符号断点,最好使用通常的断点。但是在这种情况下,我还需要在自己的类中添加一些更改,这对我来说不是很合适。

【问题讨论】:

  • 如果你使用Xcode设置断点(即点击方法左侧的gutter)呢?
  • facepalm 每次调用这个方法都必须点击左边吗?
  • 你傻吗?我已经写过我可以做到,但我不想在项目中查看每个调用,因为它们的数量
  • 我不明白这里发生了什么;我以为我已经回复了您的第二条评论,但我再也看不到它了。我也不明白你为什么要问我是不是傻。
  • 一般来说,我描述了一个很难完全手动执行的任务,并询问如何至少部分地自动化它。然后你“建议”我在一个问题中描述的完全手动的方式。我该如何应对?

标签: ios objective-c xcode debugging uiview


【解决方案1】:

如果我理解正确,您想在 -[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 命令行也有一个“选择器中断”类型,它将中断给定选择器的所有实现。没有 UI 方法可以调用它,但在控制台中你可以这样做:

(lldb) break set -S setFrame:

所以你可以在所有 setFrame: 方法上设置一个断点,然后添加相同的条件(你可以通过将-c 标志传递给break set 命令来做到这一点。如果这个断点最终匹配了太多的函数,您可以通过使用break list 查找其索引来禁用单个命中,然后使用您将在break list 输出中看到的bkpt.loc 表单逐一禁用它们。

【讨论】:

  • 看来你已经完全了解我了。但我得到error: use of undeclared identifier 'self'。也许我还应该做更多的事情?
  • 是的,你不能使用“self”,因为你在没有调试信息的代码中设置了这个断点。我在上面使用了 $arg1,这是第一个参数传递寄存器的 lldb 符号。之所以可行,是因为 self 将作为第一个参数传入,并且当 self 尚未从该寄存器中复制出来时,我将在函数的开头停止。
  • 对不起,我还是不明白怎么用。我得到同样的错误:error: use of undeclared identifier '$arg1'。如何正确使用?
  • 您在调试 32 位 x86 二进制文件吗? 32 位 x86 不使用寄存器进行参数传递,它在堆栈上传递。所以在这种情况下,你应该使用:(id)($esp+4) 而不是 $arg1。这个问题已经在这里讨论过:stackoverflow.com/questions/30470217/…
  • 差不多。我关注了您的链接并使用了*(id*)($esp+4)。您能否将有关这些各种参数的信息添加到您的答案中?所以我可以批准它作为答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-06
  • 2015-05-11
  • 2012-05-12
  • 2012-01-06
  • 1970-01-01
相关资源
最近更新 更多