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
help
罗列出的所有方法中呢,就挑最常用的几种,比如:po/p/expression等,下面详细描述下:
print obj
print obj
使用中用 p 代替即可,很明显这个是个打印命令
expression obj
expression obj
改变程序实际参数的值,目的是方便了调试:不用重新运行项目
比如上面截图中的数组arr初始化数据为@[@”1”,@”2”,@”3”,@”4”,@”5”,@”6”,@”7”,@”8”];通过expression 修改元素为打印出来的结果。
po obj
po obj
平时用的比较多的“po”,它是“print object”的简写,po一下可以看到对象的详细信息
call obj
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]
po [view rescursiveDescription]
由上打印结果也能看出当前视图层级,只是没有View Debug来的直观
po [[[UIApplication sharedApplication] keyWindow] recursiveDescription]
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、空引用