关于xcode:如何在Objective-C中使用符号断点获取参数

我有一个看起来像这样的断点

1

-[UITableViewCell setSelected:]

并且可以正常工作,但是我无法弄清楚如何获得传入的值。

我尝试了-[UITableViewCell setSelected:(BOOL)what]和-[UITableViewCell setSelected:what]根本不起作用。

如何访问参数?

如果这不起作用,我必须制作一个DebugUITableViewCell只是为了看看发生了什么事情,这很麻烦并且涉及很多代码。


如果在设备上调试代码,则遇到断点时的参数将始终位于寄存器r0,r1和r2中。如果使用po $r0,则会看到该对象收到setSelected。如果使用po $r1,则将获得"没有可用的Objective-C描述",因为这是选择器。检查$ r2以查看是否将所选内容设置为YES或NO。在i386上也有类似的故事,但是我不记得使用了哪些寄存器。


在LLDB上的Simulator中使用

p $arg3

对于第一个参数。


您可以使用自己的实现替换-[UITableViewCell setSelected:]以进行调试。下面,将调用UITableViewCellSetSelected而不是UIKit的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

static void (*__originalUITableViewCellSetSelected)( UITableViewCell *, SEL, BOOL ;
static void UITableViewCellSetSelected( UITableViewCell * self, SEL _cmd, BOOL b )
{
    // your code here... (or set a breakpoint here)
    NSLog(@"%@<%p> b=%s\
"[ self class ], self, b ?"YES" :"NO" ;

    (*__originalUITableViewCellSetSelected)( self, _cmd, b // call original implementation:
}

@implementation UITableViewCell (DebugIt)

+(void)load
{
    Method m = class_getInstanceMethod[ self class ], @selector( setSelected;
    __originalUITableViewCellSetSelected (void(*)(id, SEL,BOOL))method_getImplementation( m ;
    method_setImplementation( m(IMP)UITableViewCellSetSelected ;
}

@end


对于没有源代码的方法,以下工作:将符号断点放入其中,以便调试器在方法的第一行停止。确保已选中顶部堆栈框架。然后:

在Objectice-C方法中

  • po $arg1打印自我
  • po $arg3打印第一个参数,其余参数打印在$arg4,$arg5等中。

在C函数中,参数始于$arg1

这在IOS设备和模拟器上均有效。


基于-[UIApplication sendAction:toTarget:fromSender:forEvent:]符号,我们可以添加符号断点以检查哪个发送方已将操作发送到了哪个目标。

我们使用以下方法创建符号断点:

  • 符号:-[UIApplication sendAction:toTarget:fromSender:forEvent:]
  • 调试器命令行操作:
    • po"Target"
    • po $arg4
    • po"Sender"
    • po $arg5

输出为:

"Target" "Sender"
>

因此,正如@Dan所说,方法参数以参数3(po $arg3)开头。

posted @ 2021-09-29 21:47  zzfx  阅读(328)  评论(0编辑  收藏  举报