如何基于对象字符串属性在Xcode中设置条件断点?


90

我希望能够在达到特定字符串匹配时使调试器中断。例如,我可能会有这样的事情:

Foo myObj = [self gimmeObj];

myObj可能有一个名为的属性name。我希望调试器在以下情况下停止分配

[myObj.name isEqualToString:@"Bar"];

如何在Xcode中设置条件断点来做到这一点?

Answers:


184

您可以通过正常设置断点来在Xcode中设置条件断点,然后按住Control键单击并选择“编辑断点”(选择“运行”->“显示”->“断点”)。

在断点条目中,有一个Condition列。

现在,需要牢记几个问题。首先,gdb无法理解点语法,因此必须使用[myObj name](除非name是ivar)代替myObj.name。

接下来,与gdb中的大多数表达式一样,您必须告诉它返回结果的类型,即“ BOOL”。因此,将条件设置为:

(BOOL)[[myObj name] isEqualToString:@"Bar"]

通常,通过临时添加如下代码在代码中执行此操作通常会更容易:

if ( [myObj.name isEqualToString:@"Bar"] ) {
    NSLog( @"here" );
}

然后在NSLog上设置断点。然后,您的条件可以任意复杂,而不必担心gdb可以解析和不能解析的内容。


11
不同之处在于通过改变你的代码运行忘记删除你的日志或改变行为的风险
帕尔Brattberg

3
确实如此。我经常通过在字符串中添加“ NYI”(未实现)来缓解这种情况,然后我对NYI进行的预发布检查将捕获该字符串。
Peter N Lewis

17
为了使此工作正常进行,我必须将(bool)大写为(BOOL),可能是LLDB。
Wex 2012年

1
bool在GDB中对我不起作用,我必须使用BOOL或int –区别在此处stackoverflow.com/a/544250/725871进行了说明。
Chaosphere2112

2
如果每200个游戏错误最终都会出现,则不能将其放入代码中,现在您需要执行条件断点。停止程序以更改代码不是一种选择。
Almo

17

这是使用XCode lldb条件断点的方法。

首先,双击断点(或右键单击edit breakpoint),您会看到一个对话框弹出。

在此处输入图片说明

这些选项的含义如下:

  1. 条件:仅在此条件下才会触发断点。
  2. 忽略:触发​​断点之前条件需要满足的次数
  3. 动作:在断点中断后运行的动作。
  4. 选项:评估操作后自动继续

这是一个摘要。对于图像中的上述示例,这意味着当变量buildingId等于13时,请在此处中断。如果我将忽略时间添加到1,则当buildingId等于13 时它将第一次忽略,并在第二次满足条件时中断。

对于操作,当您按添加操作时,将有一个选择列表。通常,我要做的是使用Debugger Command po打印需要检查的变量,并且我相信使用动作比使用我有更好的方法。

如果您在运行时更改条件,似乎必须重新编译并运行应用程序


可能是因为该问题是关于基于字符串值在断点处停止[我不是失败者]
ZS

1
谢谢,非常有帮助。这个答案值得更多投票。
andreskwan

7

我不确定这是否行得通,但是您可以尝试在该行代码中设置断点,打开调试器控制台(Cmd + Shift + R),然后键入

condition N (int)[[myObj name] isEqualToString:@"Bar"]

其中,N由断点的数目(整数)代替。


2

如果使用设置器对myObj.name进行了更改,则-[MyObjClass setName:]可以从调试器控制台或Xcode的“运行”->“管理断点”->“添加符号断点”菜单中添加符号断点。如果不是(为什么不这样做(除了在指定的初始化程序或dealloc中,您可能不应该直接修改实例变量)),则可以在gdb中设置观察点(调试器运行后,在Xcode中使用调试器控制台)。页解释了如何。我不相信Xcode会公开一个不使用调试器控制台即可设置观察点的UI。


0

有时,在使用Frameworks(调试版本)时,需要在某些文件/位置设置一个断点,该断点难以导航或在开发中的框架中未公开公开。一种选择是编写一个帮助程序类以触发条件断点并使进入/退出更加容易。

- (void)invokeFrameworkMethod {
    ...
    [DebugConditionalBreakPointHelper breakPointCondition:YES comment:@"from invokeFrameworkMethod."];
    ...
}

正在开发的框架中的标头声明。

#import <Foundation/Foundation.h>

@interface DebugConditionalBreakPointHelper : NSObject
+ (void)breakPointCondition:(BOOL)enabled comment:(NSString *)comment;
@end

和执行文件:

#import "DebugConditionalBreakPointHelper.h"

@implementation DebugConditionalBreakPointHelper
+ (void)breakPointCondition:(BOOL)enabled comment:(NSString *)comment {
    if (enabled)
    {
        NSLog(@"Triggerred Conditional Break Point. Comment: %@");
    }
}
@end
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.