iOS开发之Xcode常用调试(Debug)技巧总结
一、Xcode 调试技巧之:NSLog
上面也提到了,在我们日常的开发过程中最常⻅的Debug方式就是打Log。而在OC语言中,打Log是采用NSLog方 法。但是NSLog效率低下,具体原因可以看这篇博客( NSLog效率低下的原因及尝试lldb断点打印Log)。所 以在平时的开发过程中,能不打Log就不打Log。实在想打Log网上也有对NSLog的一些优化方法,可以阅读王巍 的《宏定义的黑魔法 - 宏菜⻦起⻜手册》如下代码便出自其中
#ifdef DEBUG
#define NSLog(format, ...) printf("[%s] %s [%d] %s\n", __TIME__, __FUNCTION__, __LINE__, [[NSString stringWithFormat:format, ##__VA_ARGS__] UTF8String]);
#else
#define NSLog(format, ...)
#endif
另外在使用NSLog的时候应当注意,release版本中应该要去掉NSLog。
2、Xcode调试技巧之:LLDB
LLDB
全称Low Level Debugger
,并不是低水平的调试器,而是轻量级的高性能调试器
,默认内置于Xcode中。LLDBDebug
在编译后就是一个 Macho
的可执行文件,也可理解为 镜像文件
,image
并不是图像的意思,而是代表镜像
。这里跟上我们自己的工程名,即用image定位寻址
才是寻找我们自己的代码。
1. p 和po 命令
p 命令是 print 的缩写,查看基本数据类型的值,如果使用p命令查看的事对象,那么只会返回对象的额指针地址,p 命令后面除了可以接收变量,常量,还可以接 表达式。
po:print object的缩写,表示显示对象的文本描述,如果对象不存在则打印nil。
❌p 和 po 都不可以使用宏❌
简单的打印一个对象我们就不说了,我们来说说特殊的应用场景吧!
应用场景:你想知道一个视图包含了哪些子视图。当然你可以循环打印子视图,但是下面只需要一个命令即可解决。
输出视图层级关系(这是一个被隐藏的命令): `po [[self view] recursiveDescription] `
2. call:执行一段代码
call NSLog(@"%@", @"yang")
3. expr:动态执行指定表达式
expr i = 101
输出: (int)$0 = 101
4. bt:打印当前线程堆栈信息
如果要打印所以线程堆栈信息,使用:bt all即可。
使用bt 命令可以查看函数调用堆栈,使用bt all 可以查看所有堆栈信息,然后使用frame select 即可查看对应函数详细,同时配合up
和down命令追踪函数的调用和被调用关系。演示如下:
5. image:常用来寻找栈地址对应代码位置:
举个栗子:
应用场景数组越界模拟代码,报错后执行:image lookup --address 0x00000001035230ae
** 6. x命令
x命令是查看地址在内存的情况,一般查看对象地址和对象的属性地址
x/4gx命令:打印4个16进制地址。
x/8gx命令:打印8个16进制地址。
关于LLDB 其他使用可以学习:
iOS之Xcode断点调试
LLDB官网
三、Xcode调试技巧之:断点调试(breakpoint)
Xcode断点分以下几种:
Xcode工具栏切换到断点处,选择左下角 + 号:
可以看到断点类型:
- Swift Error Breakpoint
- Exception Breakpoint
- OpenGL ES Error Breakpoint
- Symbolic Breakpoint
- Constraint Error Breakpoint
- Test Failure Breakpoint
3.1 Breakpoint(断点)调试
看这6种断点之前,先来介绍一下,如何编辑断点:
根据需要加断点,鼠标在断点上右键:
可以看到上图五种类型:
- Edit Breakpoint
- Disable Breakpoint
- Disable Other Breakpoints
- Delete Breakpoint
- Reveal in Breakpoint Navigator
1. Edit Breakpoint
点击Edit Breakpoint后(使用比较频繁):
可以看到有5种操作条件:
- name (断点名称)
- Condition(条件)
- Ignore(忽略)
- Action(执行语句)
- Options
(1) Name 和 Condition
Condition可以输入一个条件表达式,如果条件满足了,就会触发断点,例如:
使用比较频繁,往往在处理数据时for循环找到指定对象时用到,当然还有其他用法,因场景而异。
(2) Ignore
设置忽略断点的次数,比如设置2,在上述例子中,会忽略前两次次for循环,而在第三次时触发断点
(3) action
点击 Action
默认是Debugger Command (会记忆你上次选择的类型),点击会有6种类型。
- AppleScript
- Gapture GPU Workload
- Debugger Command
- Log Message
- Shell Command
- Sound
功能Debugger Command和Log Message比较常用
1.AppleScript
会在断点触发的时候执行Mac OS X内置的一种功能强大的脚本语言。
2.Gapture GPU Gapture GPU Workload
调试跟GPU相关的问题:
3.Debugger Command
可以输入LLDB命令:
我们常常使用expr(expression简写,两种写法lldb都会识别)在断点处强行修改变量值
4.Log Message
%B输出断点的名称
%H输出断点执行的次数
@@之间输入表达式,比如(@5*2@ 会输出结果10,也可以输出对象结果)
勾选Log message to console,会在控制台输出结果。
勾选Speak message,不会在控制台输出,但是会朗读处结果(用的少)。
5.Shell Command
点击Choose,选择写好的脚本文件,触发断点时会执行所选择的脚本
6.Sound
会在断点处触发声音,如下图,有14中声音。
(4) Options
勾选Automatically continue after evaluating actions
之后程序会在断点产生后继续运行。一般用于断点处修改值,或者输出断点信息时会勾选此选项,运行时,断点生效,但是断点处不停。如图,执行for循环结束,断点处并没有停留。
3.2 Disable Breakpoint
点击Disable Breakpoint后会使断点失效,但断点依然保留,颜色会边浅色(快速使断点失效方法:鼠标单击断点)。
再次鼠标在断点处右键:
点击Enable Breakpoint断点重新生效(快速使断点生效方法:鼠标单击断点)。
3.3 Disable Other Breakpoints
点击Disable Other Breakpoints 快速将其他断点设为无效状态。这个蛮好用的
3.4 Delete Breakpoint
点击Delete Breakpoint删除断点(快速删除断点方法:鼠标左建按住断点拖走松开鼠标,即删除断点)。
3.5 Reveal in Breakpoint Navigator
点击Reveal in Breakpoint Navigator,会切换到导航断点处