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

时间:2013-03-20 00:22:24

标签: objective-c xcode debugging lldb

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

-[UITableViewCell setSelected:]

并且它有效,但我无法弄清楚如何获取传入的值。

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

如何访问参数?

如果这不起作用,我将不得不制作一个DebugUITableViewCell只是为了看看发生了什么,这很麻烦,并触及了很多代码。

5 个答案:

答案 0 :(得分:29)

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

答案 1 :(得分:10)

在模拟器上使用LLDB

p $arg3

表示第一个参数。

答案 2 :(得分:4)

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

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\n", [ 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

答案 3 :(得分:1)

根据-[UIApplication sendAction:toTarget:fromSender:forEvent:]符号,我们可以添加符号断点来检查哪个发件人已向哪个目标发送了操作。

我们用:

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

输出将是: "Target" <project.TargetViewController: 0x14ddb1470> "Sender" <UIButton: 0x14de86000; frame = (331 7; 49 30); opaque = NO; layer = <CALayer: 0x174237020>>

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

答案 4 :(得分:1)

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

在Objectice-C方法中

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

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

这同时适用于IOS设备和模拟器。