94

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

Foo myObj = [self gimmeObj];

myObj可能有一个名为name. 我希望调试器在分配时停止

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

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

4

5 回答 5

189

您可以通过正常设置断点的方式在Xcode中设置条件断点,然后按住Control键点击它并选择Edit Breakpoint(选择Run -> Show -> Breakpoints)。

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

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

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

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

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

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

然后在 NSLog 上设置断点。那么你的条件可以任意复杂,而不必担心 gdb 能解析什么,不能解析什么。

于 2009-06-13T02:53:11.153 回答
26

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

首先,双击断点(或右键edit breakpoint),可以看到弹出对话框。

Xcode 12 于 2021 年 4 月 22 日更新: 在此处输入图像描述

以下是这些选项的含义:

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

这是一个总结。对于上图中的例子,它意味着当变量testedString等于 时"Testing",在此处中断。如果我将忽略时间添加到 1,那么它将在第一次testedString等于时忽略"Testing"并在第二次满足条件时中断。

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

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

于 2017-02-15T22:10:56.463 回答
7

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

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

其中 N 替换为断点的编号(整数)。

于 2009-06-12T19:38:38.187 回答
2

如果您使用 setter 更改 myObj.name,您可以-[MyObjClass setName:]从调试器控制台或 Xcode 中的 Run->Manage Breakpoints->Add Symbolic Breakpoint 菜单添加符号断点。如果不是(为什么不呢?您可能不应该直接修改实例变量,除非在指定的初始化程序或 dealloc 中),您可以在 gdb 中设置观察点(在调试器运行后使用 Xcode 中的调试器控制台)。这个页面解释了如何。我不相信 Xcode 会在不使用调试器控制台的情况下公开用于设置观察点的 UI。

于 2009-06-12T19:59:25.453 回答
0

有时在使用框架(调试构建)并需要在某些文件/位置放置断点时,该断点难以导航或未在正在开发的框架中公开公开。一种选择是编写一个辅助类来触发条件断点并使步入/步出更容易。

- (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
于 2017-02-08T19:23:57.683 回答