『导言』
iOS利用Xcode进行Debug
调试的技巧很多,比如最常见的方式是打印Log,在一些工程中处处可见NSLog
。还有就是打断点
的Debug
方式等。诸如此类,下面就自己在开发过程中常用的Xcode调试技巧简单的做个总结。(断点调试demo下载)
声明: 此文仅为我个人理解,有不正确的地方请提出宝贵的意见
和建议
!谢谢!
一、Xcode调试技巧之:NSLog
在OC语言中,打Log是采用NSLog方法。但是NSLog效率低下,可以打印出具体位置方法:(调试输出Debug.h文档下载)
#ifdef DEBUG
#define DLog(fmt, ...) NSLog((@"[文件名:%s]\n" "[函数名:%s]\n" "[行号:%d] \n" fmt), __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__);
#define DeBugLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#define NSLog(...) NSLog(__VA_ARGS__);
#define MyNSLog(FORMAT, ...) fprintf(stderr,"[%s]:[line %d行] %s\n",[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
#else
#define DLog(...)
#define DeBugLog(...)
#define NSLog(...)
#define MyNSLog(FORMAT, ...)
#endif
- 注意:
release
版本中应该要去掉NSLog
。 - 例如:
- 代码
NSArray *array = @[@"wo",@"shi",@"apple"];
DLog(@"打印数组%@",array);
- 打印结果(类名+方法+行号+打印内容)
2017-03-31 17:08:23.730 控制台调试[20594:350839] [文件名:/Users/zhaowenjuan/Desktop/ÊéßÂà∂Âè∞Ë∞ÉËØï/ÊéßÂà∂Âè∞Ë∞ÉËØï/ViewController.m]
[函数名:-[ViewController touchesBegan:withEvent:]]
[行号:43]
打印数组(
wo,
shi,
apple
)
二、Xcode调试技巧之:LLDB
- 断点调试执行命令:
序号 | 命令 | 说明 | 翻译 | 范围 |
---|---|---|---|---|
1 | c /continue |
goto next breakpoint; | 去执行下一个 断点 |
断点间 |
2 | n /next |
step over | 跳到某个断点方法内部 |
断点内 |
3 | s /step |
step into | 跳到某个断点内部的下一个 位置 |
断点内 |
4 | finish |
step out | 退出 某个断点内部的位置 |
断点内 |
-
断点执行命令示例图:
- 断点调试打印命令
序号 | 命令 | 说明 | 举例子 |
---|---|---|---|
1 | po | print object 的缩写,表示显示对象的文本描述,如果对象不存在则打印nil |
命令:po num 输出 :8 |
2 | p | 打印基本数据类型 |
命令:p i 输出:(int) $0 = 30 |
3 | call | 执行一段代码一般只在不需要显式输出 ,或是无返回值 时使用call,用于动态 调试插入调用代码 |
命令:call NSLog(@"%@", @"zwj") |
4 | expr | 动态执行指定表达式 |
命令:expr i = 101 输出:(int)$0 = 101 |
5 | bt | 打印当前线程堆栈信息; 如果要打印 所有 线程堆栈信息,使用:bt all 即可。 |
\ |
6 | image | 常用来寻找栈地址对应代码位置:行号 |
例如:NSArray *array = @[@"yang",@"she",@"bing"];NSLog(@"%@",array[3]); 命令输入: image lookup --address 0x0000000104c25550 输出: Address: 控制台调试[0x000000010000145a] (控制台调试.__TEXT.__text + 1178) Summary: 控制台调试 -[ViewController touchesBegan:withEvent:] + 1178 at ViewController.m:43 重点代码: image lookup --address |
- 补充:命令
image
- 问题:命令
image
,如何来寻找栈地址对应代码具体位置?(根据地址找到类中的位置,如行标line
)
- 问题:命令
- 例如: 应用场景(数组越界)模拟代码:
NSArray *array = @[@"yang",@"she",@"bing"];
NSLog(@"%@",array[3]);
错误信息如下:
2017-03-31 18:17:24.200 控制台调试[21406:433320] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 3 beyond bounds [0 .. 2]'
*** First throw call stack:
(
0 CoreFoundation 0x000000010f86ed4b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000010f2d021e objc_exception_throw + 48
2 CoreFoundation 0x000000010f7a92bb -[__NSArrayI objectAtIndex:] + 155
3 控制台调试 0x000000010ecfb44a -[ViewController touchesBegan:withEvent:] + 1178
4 UIKit 0x000000010fea9f6b forwardTouchMethod + 348
5 UIKit 0x000000010fea9dfe -[UIResponder touchesBegan:withEvent:] + 49
6 UIKit 0x000000010fd02285 -[UIWindow _sendTouchesForEvent:] + 2043
7 UIKit 0x000000010fd03c33 -[UIWindow sendEvent:] + 4011
8 UIKit 0x000000010fcb09ab -[UIApplication sendEvent:] + 371
9 UIKit 0x000000011049d72d __dispatchPreprocessedEventFromEventQueue + 3248
10 UIKit 0x0000000110496463 __handleEventQueue + 4879
11 CoreFoundation 0x000000010f813761 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
12 CoreFoundation 0x000000010f7f898c __CFRunLoopDoSources0 + 556
13 CoreFoundation 0x000000010f7f7e76 __CFRunLoopRun + 918
14 CoreFoundation 0x000000010f7f7884 CFRunLoopRunSpecific + 420
15 GraphicsServices 0x000000011365aa6f GSEventRunModal + 161
16 UIKit 0x000000010fc92c68 UIApplicationMain + 159
17 控制台调试 0x000000010ecfb83f main + 111
18 libdyld.dylib 0x00000001126d068d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
这个时候我们如果怀疑出错的地址是0x000000010ecfb44a
,那么我们可以使用下面命令来找出错误代码的位置:
image lookup --address 0x000000010ecfb44a
执行命令后输出结果如下:
(lldb) image lookup --address 0x000000010ecfb44a
Address: 控制台调试[0x000000010000144a] (控制台调试.__TEXT.__text + 1178)
Summary: 控制台调试`-[ViewController touchesBegan:withEvent:] + 1178 at ViewController.m:43
- 结果分析:从上面输出结果中可以看出,错误位置应该是
ViewController.m
文件中的第43
行。 -
链接:
1 .iOS开发之Xcode常用调试技巧总结