Xcode 调试技巧

11 篇文章 1 订阅
2 篇文章 0 订阅
首先说一下Xcode中添加断点的方法,很简单,用鼠标在想要添加断点的行的行号上单击,即可生成一个深色的箭头标识(断点):
Xcode 调试技巧 - 远行的风 - 风的驿站
如果想要禁用(Disable)断点,在断点上单击一下,断点变为浅蓝色,此时,断点仍然存在,但是运行时不会起作用:
Xcode 调试技巧 - 远行的风 - 风的驿站
在运行时,我们如果加入了很多断点,可以用Comand+Y快捷键,或者点击调试菜单中的按钮来禁用/启用全部断点:
Xcode 调试技巧 - 远行的风 - 风的驿站
如果想要删除断点,在断点上右键菜单中选择删除即可。

好了,书归正传,我们介绍一下常用的调试技巧。
首先新建一个测试工程,创建一个简单的Person类,定义如下:

#import <Cocoa/Cocoa.h>


@interface Person : NSObject{

    int age;

    NSString* name;

}


@property int age;

@property NSString* name;


- (id)initWithName:(NSString*) name andAge:(int) age;


@end


类定义:

#import "Person.h"


@implementation Person


@synthesize name;

@synthesize age;


- (id)initWithName:(NSString*) n andAge:(int) a{

    if (self = [super init]) {

        self.name = n;

        self.age = a;

    }

    

    return self;

}


- (NSString*)description{

    NSString* desc = [NSString stringWithFormat:@"name:%@   age:%i",name, age];

    return desc;

}


@end


接着在Main函数中添加测试代码:

int main(int argc, const char * argv[])

{

    NSMutableArray* persons = [NSMutableArray array];

    for (int i = 0; i < 10; i++) {

        Person* person = [[Person alloc] initWithName:[NSString stringWithFormat:@"Person%i", i] andAge:i];

        [persons addObject:person];

    }

    

    for (Person* p in persons) {

        BOOL flag = true;

        if (flag) {

            NSLog(@"%@", p);

        }

    }

    

    return 0;

}


我们在第一个for循环中的“[persons addObject:person];”语句在行添加断点,然后运行程序,程序执行到断点处,我们在lldb窗口(右下方)中输入po person,可以输出当前person对象的属性值

Xcode 调试技巧 - 远行的风 - 风的驿站

这里po代表print object,也就是打印对象(object),如果这个对象重载了description方法,则po命令会调用对象的这个方法进行输出(本例中我们重载description就是这个目的),否则po命令会打印当前对象的起始内存空间地址。

我们接着在lldb窗口中输入p person.name命令,可以打印出person对象的name属性的地址和值:

Xcode 调试技巧 - 远行的风 - 风的驿站

这里p命令代表print,用来打印基本类型(如int,BOOL,char,float等等)


接着我们来看如何用lldb的expr命令来修改变量的值:

仍然在刚才的位置添加断点,执行到age=2的person时,我们在lldb窗口中输入expr person.name=@"changed name",然后我们disable掉这个断点,在main函数的return 0;这句添加断点,然后按快捷键Control+Command+Y执行到新添加的断点,在窗口中我们查看lldb窗口中第二个for循环的输出,发现age=2的person的名字变成了“changed name”:

Xcode 调试技巧 - 远行的风 - 风的驿站

另外有一个小技巧,当程序执行过程中我们想程序返回到之前执行的语句时,我们可以通过拖拽程序的运行指示箭头来实现:
Xcode 调试技巧 - 远行的风 - 风的驿站

接着我们来说一下条件断点,右击断点,在弹出菜单中选择编辑断点(Edit Breakpoint),弹出如下菜单:
Xcode 调试技巧 - 远行的风 - 风的驿站
这里我们可以再Condition中填入运算结果为boolean值的表达式,当表达式为“真”的时候,断点会生效,当表达式为“假”的时候,断点不生效。例如,我们编辑 [persons  addObject :person]; ”语句 在行的断点,添加条件:person.age == 4,然后我们执行程序,在第一次程序执行到断点时,我们用po person打印当前的person对象,发现person的age为4,继续执行,发现程序直接执行到了最后,也就是第一个for循环中断点只在age=4时生效了。
我们再看一下Ignore后面的数字,这个数字允许我们设定当前断点在多少次程序 执行 经过之后生效,我们将Condition清空,然后我们设置Ignore后面为5,执行,发现第一次断点生效的时候i=5:
Xcode 调试技巧 - 远行的风 - 风的驿站
我们继续执行循环,发现i=6,7,8,9的时候断点依然生效。
我们再来看Action,点击“Add Action”,选择“Debugger Command”,输入如下命令并勾选Options中的“Automatically continue after evaluating”:
Xcode 调试技巧 - 远行的风 - 风的驿站
然后我们运行查看lldb窗口中的输出:
Xcode 调试技巧 - 远行的风 - 风的驿站
可以看到,从i=5开始,person的名字都变成了“changed name”,并且整个过程中断点没有生效。名字修改的操作从i=5开始,是因为我们定义了Ignore参数,改名字是Debugger Command中定义的,而断点没有生效是最后的Options的选项设置的。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值