xcode调试心得

没有系统的学习和总结过Xcode调试相关的知识,这里参考http://www.raywenderlich.com/里面的教程,总结一下调试相关的知识,算半拉翻译,半拉总结吧
崩溃的表现一般来说:
SIGABRT(好处理)
EXC_BAD_ACCESS(一般内存问题)
SIGBUS
SIGSEGV

左面工具栏会按照线程分出bug所在,thread1一般主线程,其他线程的问题会在自己的位置显示。点开里面的方法都是看不懂的汇编(其实以前学过)。
对于Xcode下方有提示的bug一般很好解决,但是有时候只是简单的EXC_BAD_ACCESS,无从下手,左面工具栏中的方法也看不出所以然,这时要把顶部工具栏的breakpoint打开,也许左面就会显示出更多出问题的方法,如图打开brekpoints以后多出了所选的方法提示,找到了是数组的问题。当然也可以在左面下方滑块调节来显示出更多提示的方法。
总结的来说,就是在左面栏里找到出问题的地方
App启动的流程

上面的图的调用关系说明了App是怎么启动的,除了main方法,其他方法都是看不到的,默认封装到系统的framework里,没法看源码
方法引用错误一般来说:

[UINavigationController setList:]: unrecognized selector sent to instance 0x6d4ed20

1

[UINavigationController setList:]: unrecognized selector sent to instance 0x6d4ed20

这种要不就是这个类没这个方法,或者调用方法的对象错误,或者拼错,比较简单
看打印信息

没有打印信息的时候,可以点这个,有时候需要多点几次,可以有更详细的错误打印信息,lldb调试输入c功能是一样的,都是让程序继续运行
This class is not key value coding-compliant

Problems[14961:f803] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is notkey value coding-compliant for the key button.'

1
2
3
4
5

Problems[14961:f803] *** Terminating app due to uncaught exception 'NSUnknownKeyException',

reason: '[ setValue:forUndefinedKey:]: this class is not

key value coding-compliant for the key button.'

1.有时会碰到这种错误,印象里是请求的网络列表返回为空,出现了个这么诡异的现象,这是一种情况。
2.NSUnknownKeyException指示了未知的key,而这个未知的key出现在MainViewController里,这个key的名字是button
先看nib,在这个例子里有一个button,和MainViewController的属性button连接了IBOutlet,但是@property对应的@synthesize没有写,出现了这个问题,虽然在iOS6可以不用写@synthesize了,但是在老版本可能还会出现这个问题
3.总结一下,“This class is not key value coding-compliant”这个问题出现在NIB相关的地方,一般是iboutlet已经连接,但是这个属性却不存在,常常发生在ib连着呢,属性给删了。
使用DEBUGGER

[self performSegueWithIdentifier:@"ModalSegue" sender:sender];

1

[self performSegueWithIdentifier:@"ModalSegue" sender:sender];

这句话出问题了,不知道怎么处理,可以在左面选中抛出的异常expection_throw
用LLDB的debugger po $eax会调用description方法,打印全部信息

po是point object,$eax是当前cpu注册者之一,如果选中了异常错误输入这个命令,这个注册者就是NSException对象,注意$eax是用于模拟器的,真机要用$r0
可以看大原因了,是segue问题,storyboard中的问题这里就定位了
类似的,还有这些debugger方法

po [$eax class] //可以看到 (id) $2 = 0x01446e84 NSException,数字不重要NSException是问题的名字po [$eax name]//得到exception的名字po[$eax reason]//得到错误原因(unsigned int) $4 = 114784400 Receiver () has no segue with identifier 'ModalSegue'

1
2
3
4
5

po [$eax class] //可以看到 (id) $2 = 0x01446e84 NSException,数字不重要NSException是问题的名字

po [$eax name]//得到exception的名字

po[$eax reason]//得到错误原因(unsigned int) $4 = 114784400 Receiver () has no segue with identifier 'ModalSegue'

NSAssert用法

- (void)doSomethingWithAString:(NSString *)theString{NSAssert(theString != nil, @"String cannot be nil");NSAssert([theString length] >= 3, @"String is too short");. . .}

1
2
3
4
5
6
7
8
9
10
11

- (void)doSomethingWithAString:(NSString *)theString

{

NSAssert(theString != nil, @"String cannot be nil");

NSAssert([theString length] >= 3, @"String is too short");

. . .

}

NSAssert最为一种防御型的代码,目的就是一有错,程序就伴随着异常崩溃,或者说停止运行,不往下进行。上面的代码当传入空数组的时候就会打印这个:

2013-07-24 11:25:14.777 Problems[792:c07] *** Assertion failure in -[MainViewController doSomethingWithAString:], /Users/lipengxuan/Downloads/Problems/Problems/MainViewController.m:20

1

2013-07-24 11:25:14.777 Problems[792:c07] *** Assertion failure in -[MainViewController doSomethingWithAString:], /Users/lipengxuan/Downloads/Problems/Problems/MainViewController.m:20

有的时候程序崩溃打印信息就会出现Assertion,那么就是这句话起作用了,这个时候可以继续运行(lldb c),可以看到更详细的打印信息。
总结一下,遇到Assertion failure,就可以下一步运行看更详细的信息

BreakPoint使用breakpoint 分Exception breakPoint和breakPoint
Exception breakPoint:程序崩溃异常了会立刻暂停到断点,点加号第一个就是添加Exception断点

breakPoint:随意放
Finally!终于到了传说中的打断点,这个很基本很经典的调试方法,事实上,断点和NSLog用法差不多,只不过不用你去写了
一个简单的例子,现在有个这么个方法

- (id)initWithStyle:(UITableViewStyle)style{ NSLog(@"init with style");if (self == [super initWithStyle:style]){ list = [NSMutableArray arrayWithCapacity:10];[list addObject:@"One"];[list addObject:@"Two"];[list addObject:@"Three"];[list addObject:@"Four"];[list addObject:@"Five"];}return self;}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

- (id)initWithStyle:(UITableViewStyle)style

{

NSLog(@"init with style");

if (self == [super initWithStyle:style])

{

list = [NSMutableArray arrayWithCapacity:10];

[list addObject:@"One"];

[list addObject:@"Two"];

[list addObject:@"Three"];

[list addObject:@"Four"];

[list addObject:@"Five"];

}

return self;

}

程序运行后我发现貌似这个方法没有执行,这是一种猜测,通常我会在方法里加入打印信息,也可以打断点,在方法定义的地方加断点,如果调用这个方法了,就会停止在这里,起到了一样的作用。
接着是单步调试
打断点,然后点击跳跃的箭头,就可以一步步的执行了,更精细的步骤可以F6,期间可以随时打印想看的变量,比如在tableview的cellForRowAtIndexPath函数中用po indexPath打印出indexPath的值

(NSIndexPath *) $3 = 0x06895680 2 indexes [0, 1]

1

(NSIndexPath *) $3 = 0x06895680 2 indexes [0, 1]

意思就是section 0 row 1
这样进行一步打印一次,可以看出indexes也在变化,知道出问题的敌方

Problems[12540:f803] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 5 beyond bounds [0 .. 4]'*** First throw call stack:(NSIndexPath *) $11 = 0x06a8a6c0 2 indexes [0, 5]

1
2
3
4
5
6
7

Problems[12540:f803] *** Terminating app due to uncaught exception 'NSRangeException',

reason: '*** -[__NSArrayM objectAtIndex:]: index 5 beyond bounds [0 .. 4]'

*** First throw call stack:

(NSIndexPath *) $11 = 0x06a8a6c0 2 indexes [0, 5]

单步调试找出来了index row=5超出了数组的范围
总结一下,po命令非常实用,只要找到正确的调用方法,就可以打印对象信息

ZOMBIES问题EXC_BAD_ACCESS问题一般是内存问题,比如下面这种情况

程序停在了这里,EXC_BAD_ACCESS问题,但是也不知道具体问题是什么,这时候可以用zombie 工具检测
Xcode点击左上角项目名字-Edit Scheme-Diagnostics-Enable Zombie Objects,OK再次运行
会多出这段话

2013-07-24 14:39:49.409 Problems[1271:c07] *** -[__NSArrayM objectAtIndex:]: message sent to deallocated instance 0x71cbe90

1

2013-07-24 14:39:49.409 Problems[1271:c07] *** -[__NSArrayM objectAtIndex:]: message sent to deallocated instance 0x71cbe90

这段话什么意思呢?
创建一个对象,alloc一个对象会分配给这个对象一块内存,党这个对象release了,引用计数归零了,这块内存就会dealloc掉,之后其他对象就可以用这块内存。
但是可能有这样一种情况,正在有对象使用的内存被另一个对象企图指向使用,或者已经被释放的内存企图再次被释放。
僵尸工具的作用是让对象被released的时候,内存不dealloc,这块内存被标记为“undead”,如果其他对象想再用这块内存,app可以识别出错误并显示“message sent to deallocated instance”,就像上面的那段话一样。结合上面的代码

cell.textLabel.text = [list objectAtIndex:indexPath.row];

1

cell.textLabel.text = [list objectAtIndex:indexPath.row];

这段话就是zombie对象出现的地方,一般来说textLabel 还有indexPath.row应该没问题,问题应该出现在list这个数组,而且zombie tool也说了是[__NSArrayM objectAtIndex:]的问题,利用NSLog打印list,可以看到内存地址和错误的地址相同,那么错误就定义在list了

2013-07-24 15:24:53.105 Problems[1334:c07] list is 0x75b0ed02013-07-24 15:24:53.105 Problems[1334:c07] *** -[__NSArrayM objectAtIndex:]: message sent to deallocated instance 0x75b0ed0

1
2
3

2013-07-24 15:24:53.105 Problems[1334:c07] list is 0x75b0ed0

2013-07-24 15:24:53.105 Problems[1334:c07] *** -[__NSArrayM objectAtIndex:]: message sent to deallocated instance 0x75b0ed0

当然用dubugger 命令 p list也可以打印出这个结果
这就是zombie 工具起的作用,解决内存问题
总结的来说,如果出现了EXC_BAD_ACCESS错误,打开僵尸工具,再试一遍。但是没问题的时候不要打开这个工具,因为这个工具从不dealloc内存,只是标记内存为”undead”,会导致内存泄露,所以用的时候再打开,诊断后再关掉。

习惯问题应该看bug一样的视线看warning,能修复就修复。

- (void)buttonTapped:(id)sender{NSLog(@"You tapped on: %s", sender);}

1
2
3
4
5
6
7

- (void)buttonTapped:(id)sender

{

NSLog(@"You tapped on: %s", sender);

}

比如这个按钮点击事件,%s是打印C-String,就是末尾是NUL的字符串,但是这里sender是按钮对象,所以会崩溃,不能忽略警告

(0)

相关推荐

  • xcode怎么调试?xcode调试方法教程

    xcode怎么调试呢?xcode将 OS X 的轻松使用,UNIX 能量以及高性能的开发技术集合在一起,具体xcode怎么调试呢?我们一起来学习一下,希望可以帮助到大家。 xcode怎么调试: xco ...

  • Xcode中的iOS模拟器(iOS Simulator)的介绍和使用心得

    iOS功能简介iOS模拟器,是在Mac下面开发程序时,开发iOS平台的程序时候,可以使用的辅助工具. 其功能是,帮你模拟iOS平台设备,在模拟器上运行对应的程序,以方便你没有实体设备的时候去调试程序. ...

  • xcode是什么 有什么用 xcode怎么用详情介绍

     xcode是什么: 下面就一起来了解一下吧 Xcode是苹果公司向开发人员提供的集成开发环境(非开源),用于开发Mac OS X,iOS的应用程序。其运行于苹果公司的Mac操作系统下。 不管你用C、 ...

  • VMware 11安装Mac OS X 10.10虚拟机以及优化心得

    要使用xcode和sketch,必须在mac环境中运行,无奈本人笔记本装黑苹果的话独立显卡和无线网卡驱动无解,不想折腾,先用虚拟机试一下。一开始虚拟机下面跑优胜美地系统简直卡出翔,一动一卡让我几乎放弃 ...

  • xcode怎么设置成中文?mac xcode中英文界面切换方法介绍

    xcode是英文的,我想改成中文,怎么改?Xcode是一款运行在操作系统Mac OS X上的集成开发工具(IDE),包含你需要创建的iPhone.iPad.苹果.苹果手表.Apple TV应用程序的一 ...

  • C语言视频OS X系统 :如何用Xcode写C语言程序

    如何用在OS X系统写一个简单的C程序,本经验主要涉及: ① 如何在Xcode创建一个C程序: ② 如何调试程序: 本人自己看尹,cheng的视频整理的,希望对大家有帮助 创建C程序 01 单击Cre ...

  • 使用GDB调试RB-tree的问题总汇

    操作方法 01 Content 1. at后面的一堆字符串代表什么? 2. 为什么没有单步进入(step in)_Rb_tree_insert_and_rebalance函数? 3. 如何通过目标文件 ...

  • 森林开局流程心得

    森林游戏很多玩家刚开始玩的时候都不知道如何上手,下面小编给大家带来了森林游戏的开局流程心得,希望可以帮助到大家。 1.走出飞机前吃一份盒饭,并带走其他所有的苏打水和烈酒。 2.走出飞机后,到飞机前方左 ...

  • ATT解锁成功心得

    小编英语烂到透顶……所以无奈之下只能“出金求带ATT解锁任务……” 今早解锁成功,以下是一点点心得。 1、传说中的T2并非不能解,非官方的APPLE信息查询结论不一定准确。 解锁之后,让一英语学霸朋友 ...