Xcode 断点调试

转自:https://www.leewong.cn/2020/07/25/howtousexcodebreakpoint/

上图是我们使用Xcode进行断点调试时,上图底部图标从左到右功能分别如下:

  • 启用/禁用断点(点击后变灰色,所有断点失效;再点击变蓝色,所有断点生效)
  • 继续执行程序(点击后跳过本次断点,继续执行程序)
  • 执行下一步(点击后执行第23行代码)
  • 进入方法(点击后进入-testLog方法)
  • 跳出方法(在-testLog方法内部点击后回到第22行代码)

除了这些功能,我们还可以编辑断点,在断点出右键选择Edit BreakPoint

下面我们来分别介绍下这几个选项以及如何设置这些选项:

Condition

Condition 表示断点条件。开发者可以在 Condition 输入框中设置触发断点的条件。比如上面 for 循环的例子我们可以在 Condition 条件中添加条件

这样我们的断点只有在index==5时才会被触发,这样就有利于我们在某些for循环时只有在满足某个条件时才触发断点。

Ignore

Ignore为忽略次数,同样我们在上面for循环的例子中可以将Ignore设置为5,那么断点第一次触发时index=6时。

Action

Action为触发动作。Action可以添加多条,在触发断点后,会紧接着执行设定的Actions。Action有6种执行类型,其中较常用的有Debugger Command和Log message。

Debugger Command

Log Message

当然log的信息还可以读出来

试一下吧,有惊喜!!!

Options

Options控制在执行断点对应的Actions后是否自动继续执行程序。勾选后Options后,断点被触发后不进入Debug界面。

接下来看下断点的正题

断点

断点类型

我们在Xocde中添加断点时有几种类型的断点:

下面介绍下常用的几种类型的断点:

Exception Breakpoint(异常断点)

当我们添加了一个Exception BreakPoint时,实际上是添加了一个全局断点

正常情况下我们的代码崩溃后,如果没有全局断点 代码会崩溃在main函数中,但是我们如果添加了全局断点,代码发生崩溃时,就会自动崩溃到出现问题的哪一行代码,比较方便我们去定位问题。

Symbolic Breakpoint (符号断点)

当我们添加一个符号断点时,会自动为我们弹出自定义面板,

与普通断点相比,符号断点的编辑界面多出来Symbol和Module两个输入框。下面我们来看下这两个输入框的作用。

Symbol

可以在Symbol输入框中设置断点触发方法/函数。在Symbol中设置一个方法/函数后,运行程序并执行到此方法时会触发断点。

如果是C语言方法那么直接使用方法名就可以

Module

可以在Module输入框中设置Symbol中的函数所在的库,以避免不同库中存在名字相同的方法/函数,默认不用填写。

Condition

与普通断点的用法基本一致
在Condition输入框中设置$arg3==nil,就会限制断点在满足第一个参数和第二个参数都为nil时才会被触发。但是实际上使用下面这种写法才可以
[(NSString *)$arg3 length] == 0

这里我们可以用来判断某个方法再被调用时,哪里的参数传递是有问题的。

Watch Breakpoint(监控断点)

有时候我们需要监听某个变量的值的变化

添加断点


断点结果
image

很可惜没有发现监听数组个数变化的断点

断点的应用

查看UI控件约束冲突

我们先看下下面这段代码:

- (void)addVCSubView {
    UIView *contentView = [[UIView alloc] init];
    contentView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:contentView];
    [contentView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.center.equalTo(self.view);
        make.width.height.equalTo(@200);
    }];


    UIView *view = [[UIView alloc] init];
    view.backgroundColor = [UIColor greenColor];
    [contentView addSubview:view];
    [view mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(contentView);
        make.centerY.equalTo(contentView);
        make.top.equalTo(contentView.mas_top).offset(20);
        make.width.height.equalTo(@100);
    }];
}
- (void)addVCSubView {    UIView *contentView = [[UIView alloc] init];    contentView.backgroundColor = [UIColor blueColor];    [self.view addSubview:contentView];    [contentView mas_makeConstraints:^(MASConstraintMaker *make) {        make.center.equalTo(self.view);        make.width.height.equalTo(@200);    }];    UIView *view = [[UIView alloc] init];    view.backgroundColor = [UIColor greenColor];    [contentView addSubview:view];    [view mas_makeConstraints:^(MASConstraintMaker *make) {        make.centerX.equalTo(contentView);        make.centerY.equalTo(contentView);        make.top.equalTo(contentView.mas_top).offset(20);        make.width.height.equalTo(@100);    }];}

具体的展示如图:

从图中我们可以很明显的看到绿色的子视图的宽高并不相同,同样在控制台上我们也看到了这样的输出

[LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<MASLayoutConstraint:0x600000e183c0 UIView:0x7fa513e11cc0.height == 200>",
    "<MASLayoutConstraint:0x600000e181e0 UIView:0x7fa516604e70.centerY == UIView:0x7fa513e11cc0.centerY>",
    "<MASLayoutConstraint:0x600000e18600 UIView:0x7fa516604e70.top == UIView:0x7fa513e11cc0.top + 20>",
    "<MASLayoutConstraint:0x600000e186c0 UIView:0x7fa516604e70.height == 100>"
)

Will attempt to recover by breaking constraint 
<MASLayoutConstraint:0x600000e186c0 UIView:0x7fa516604e70.height == 100>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

控制台提示我们 下面列表中的约束其中有一个是不需要的,同时当前展示的样子是系统通过移除了哪个约束后展示出来的

约束问题是什么

我们先看下控制台输出的提示

"<MASLayoutConstraint:0x600000e183c0 UIView:0x7fa513e11cc0.height == 200>",
"<MASLayoutConstraint:0x600000e181e0 UIView:0x7fa516604e70.centerY == UIView:0x7fa513e11cc0.centerY>",
"<MASLayoutConstraint:0x600000e18600 UIView:0x7fa516604e70.top == UIView:0x7fa513e11cc0.top + 20>",
"<MASLayoutConstraint:0x600000e186c0 UIView:0x7fa516604e70.height == 100>"

上面的提示中设计到两个UIView对象,0x600000e183c00x7fa513e11cc0,通过查看上面的约束提示,我们发现height,centerY,top,height 这几个约束都是垂直方向的约束。

上面的提示还有下面这句

Will attempt to recover by breaking constraint 
<MASLayoutConstraint:0x600000e186c0 UIView:0x7fa516604e70.height == 100>

尝试通过break高度为100的约束来正确展示这个视图,而结合我们上面展示的图片 没有生效的约束是height=100与上面的描述一致。

那通过上面的分析我们得出这次约束的问题是:

控件0x600000e183c00x7fa516604e70在垂直方向存在约束冲突,目前系统通过移除UIView:0x7fa516604e70.height == 100约束来展示UI,如果系统的修改与你的预期不符,可以通过修改上面提到的四个约束中的一个来展示出正确的UI。

哪个视图约束有问题

分析出约束的问题后,我们需要定位到底是哪两个视图出现了约束问题。

通过内存地址定位

我们可以通过查看层次结果,然后通过出现约束问题的视图的内存地址进行筛选,这样我们就能容易的定位到出现问题的视图。

通过lldb命令

我们还可以通过设置出现问题的视图的背景颜色来定位到底是哪个视图出现问题,当然是用lldb命令的前提是我们需要在合适的地方添加断点。

首先我们需要在项目中添加约束冲突(符号断点)断点,添加方法如下

添加了这个断点后,在应用启动遇到约束冲突的位置系统会,直接有约束冲突的位置设置断点,下面截取一部分发生断点时的提示

*UIButton:0x10b091670'注册/登录'- AMBIGUOUS LAYOUT for UIButton:0x10b091670'注册/登录'.minY{id: 159}   UIButtonLabel:0x10b15fb60'注册/登录'

 *UILabel:0x10b08f790'群组'- AMBIGUOUS LAYOUT for UILabel:0x10b08f790'群组'.minX{id: 136}, UILabel:0x10b08f790'群组'.minY{id: 138}, UILabel:0x10b08f790'群组'.Width{id: 135}, UILabel:0x10b08f790'群组'.Height{id: 140}

这里我们可以通过关键词 AMBIGUOUS LAYOUT 来获取所有存在约束冲突的位置,因为log中有了按钮或者label的文案我们可以很快的定位到具体位置。
当然 如果层次非常深,或者我们无法通过文案进行区分,我们还可以通过下面的命令修改视图的背景颜色来定位出现约束冲突的视图。

expr ((UILabel *)0x10b091670).backgroundColor = [UIColor yellowColor];

结果如下图:

通过上面的方法我们可以定位到出现问题的视图控件,那么我们 下一步就要看如何去解决这个约束冲突。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352

推荐阅读更多精彩内容