iOS调试技巧大全

NSLog

//保证 ifdef 中的宏定义只会在 OC 代码中被引用;
//否则一旦引入 C 或者 C++ 代码或者框架就会出错!
#ifdef __OBJC__

//只在开发中用:
#ifdef DEBUG

//定义 NSLog(__VA_AGRS__):
//#define NSLog(...)  NSLog(__VA_ARGS__)
#define NSLog(fmt, ...) NSLog((@"%s [Line %d]" fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)

//如果在非 DEBUG 情况下:
#else

//NSLog(...)后面不跟任何内容,在非 DEBUG 情况下(提交上线发布时)该 NSLog(...)自动失效!

#define NSLog(...)

//结束"ifdef DEBUG",有 以 ifdef 开始就要有 endif 结束!就酱!
#endif

//结束"ifdef __OBJC__",有 以 ifdef 开始就要有 endif 结束!就酱!
#endif

控制台打印结果如下:

断点调试

普通断点

1、快捷键添加方式 光标移动到需要断点的代码处: command + \
2、代码行旁边点击添加

再点击取消断点

条件断点

以上的断点只是最普通的,我们还能对断点的属性进行配置,设置条件,使断点更加智能化,右键断点进入编辑对话框:

1、右键断点,选择 Edit Breakpoint…

2、添加条件语句,此处OC怎么判断,条件语句就怎么写

如上截图的这个例子,此断点如果不添加条件,循环中的代码每次都要单步执行,但是加了如下的条件:

[str isEqualToString:@"5"]

遍历前4位元素的时候是会顺利执行,不会断点的,当遍历到第5位,满足条件,中断程序,进行调试。

3、添加ignore条件,忽略前n次的执行

如上图 ,4次之后才会单步执行后面的遍历,前4次是不会终止程序的。

4、查看函数调用次数

异常断点

断点的功能不限于上面所述,实际开发过程中,经常会遇见崩溃直接走到main函数,此时异常断点就派上用场了,点击 + 号选择 Exception Breakpoint…

如下即可,编辑断点,也还有相关详细设置,此处不做赘述

符号断点

符号断点创建同于异常断点,只不过点击 + 选择 Symbolic Breakpoint…即可
一般符号断点可以在你指定的[类名 方法名]时中断执行。比如指定

[ViewController viewDidLoad]

那么程序在执行到viewDidLoad都会断点调试。

假如Symbol处只添加了一个方法名如下:

那么程序会执行到doSomething这个方法时断点调试,如下:

Console(LLDB命令)

LLDB 绑定在 Xcode 内部,存在于主窗口底部的控制台中。http://lldb.llvm.org/lldb-gdb.html 这里是一份lldb命令清单,列出了lldb可用的命令。

常用的help命令,它会帮你罗列处命令列表供你选择

help

罗列出的所有方法中呢,就挑最常用的几种,比如:po/p/expression等,下面详细描述下:

使用中用 p 代替即可,很明显这个是个打印命令

expression obj

改变程序实际参数的值,目的是方便了调试:不用重新运行项目

比如上面截图中的数组arr初始化数据为@[@”1”,@”2”,@”3”,@”4”,@”5”,@”6”,@”7”,@”8”];通过expression 修改元素为打印出来的结果。

po obj

平时用的比较多的“po”,它是“print object”的简写,po一下可以看到对象的详细信息

call obj

调用的意思,可以控制台调用函数或者方法 动态改变

call  [self.view setBackgroundColor:[UIColor redColor]]

可以重设当前View背景色 无需重新运行

或者调用程序里自己定义的函数方法

call  [self doSomething]

可见虽然函数还未运行,但是call命令却是可以提前调用的。

NSZoombieEnabled

僵尸对象调试开启:

视图调试

View Debug(Xcode6往后)

Xcode6以后,苹果就已经推出了Debug View Hierarchy,也就是 视图层级调试, Xcode6之前还得去找第三方软件去查看视图层级

po 打印视图层级

po [view rescursiveDescription]

由上打印结果也能看出当前视图层级,只是没有View Debug来的直观

po [[[UIApplication sharedApplication] keyWindow] recursiveDescription]

上面这段无需打断点 ,只要暂停,然后就可以输出当前窗口上的层级树。

Reveal

第三方 视图层级查看软件,

Analyze静态分析

静态分析工具 Product->Analyze(快捷键command+shift+B)可以找出代码潜在错误,如内存泄露,未使用函数和变量,循环引用等,但是友情提醒一句: Analyze静态分析不可全信,但也不能不信。

Analyze主要的作用有:

  • 本地化问题 Localizability Issue (Apple)
  • 声明错误检查(Dead store)
  • 内存泄露检查 Memory Error
  • 逻辑错误检查 Logic Error
  • API调用错误检查 API Misuse

通过镜头分析,最后的结果会分门别类的列好如下图:

本地化问题

诸如此类,提示 User-facing text should use localized string macro…, 意思是面向用户的文本应该使用本地化的字符串宏.

这种情况一般是因为代码中配置了本地化,面向用户的应该用字符串宏,而我们直接赋值为汉字.如下:

所以解决方法:
1、直接将此处配置关闭,设置为NO
2、将项目中直接赋值的文本提出来,本地化

声明错误检查

无效数据如:Unused、Never read…. ,大致是那一类创建了但从未使用的变量

一般情况删除这些变量即可

内存泄露检查

1、一般来说都是由于使用的CoreFoundation后没有release造成的。 在RAC下Foundation框架下的不需要进行release,由于Core Foundation不在ARC管理范围内,所以需要主动release。

2、另外一些就是需要返回非空,却return nil;
3、空引用

instruments动态分析


目录