tubiebutu 2019-06-20
本文从以前做的幻灯中整理而来的,主要讲一下XCode结合LLDB调试命令以及OBJC运行时的调试技巧。
1、OPTIMIZE,Debug和Release判定
当我们想要某些代码只在Debug环境下才运行可以使用此宏定义判别
2、i386与x86_64,模拟器环境判定
有时工程依赖的Lib库只编译了真机的代码,模拟器编译出错。为了可以模拟器调试,使用此宏略过不能编译的代码
3、__IPHONE_8_0等,编译SDK的判定
__IPHONE_OS_VERSION_MAX_ALLOWED,此宏定义声明了当前编译的SDK版本,可进行比较
4、使用-D编译器选项为编译Target追加宏定义
每一个Target可为XDTarget定义不同的值,这样运行时就可以判别Target,也免去了手工修改的麻烦。
5、NOP,空语句
可以设计一个宏进行代替,用于挂载条件断点调试使用。
1、PO,输出对象信息
2、P,输出变量的值
除了值类型,也可以直接打印结构体数据
3、Call,执行一段代码
调试状态下,对于点语法支持不佳。如果发现符号未找到的情况,尝试使用发送消息的方式。如果还不行,根据提示,声明类型。对于PO、P等指令同样也需要注意
可以修改值。
配合NOP与断点,可以在运行时动态的控制程序的运行状态
可以执行一段代码
4、bt,打印调用栈
1、一个断点可以做些什么事情?
可以执行若干种类的action
当经过此断点时,执行action但是不会中断程序
2、异常断点
某些crash是由程序抛出的异常导致的,比如数组越界。可以通过添加异常断点监控异常抛出的位置。
3、符号断点
举个例子:当UIViewController被载入时触发,并将当前的调用栈输出
4、内存断点
可通过XCode调试界面简化指令添加
添加时,需要预先打断,找到要监视的内存地址(注意,地址每次启动都会失效)
可以输出值的变化。可以找出内存是何时被修改的,值是如何变化的。
以上这些调试手段虽然看起来比较简单,但只要灵活运用,就可以为调试带来很多便利和可能性。
比如下面一个例子
图中有三个变量a,b,c。只要在NOP语句加入一个执行call命令的条件断点,通过调节断点的开闭,就可以在程序运行时动态的控制a,b,c的数值。这使得不用编写调试代码,就可以模拟各个状态,动态的调试程序分支。
此外,当程序发生异常时,一般是通过控制台报错信息,被动的定位问题所在。如果使用调试命令结合OBJC的运行时,可以主动的获知发生异常的状态。在MRC开发的时代,对于多次释放对象的问题,甚至可以一定程度的将僵尸对象还原回原始的对象,从而定位问题所在。
所以只要灵活的运用上面这些调试手段,相信您也会很快成为一个调试高手。
一.代码块在哪里?如果上面这张图不小心点没了或者没出来,可以看第一步的操作,然后鼠标停留在选中的区域停留2秒以上就会出现左边的??可以将路径中的代码块,迁移到不同的电脑上使用,需重新启动Xcode ;