6.4 NSLog()函数
6.4.1 NSLog()函数基本使用
在编程的过程中,每完成一个功能时都需要进行调试来验证功能实现是否符合预期,而调试过程中打印日志是必不可少的手段之一。通过打印日志,可以验证程序的输入与输出,继而精确地定位问题的位置。在Objective-C编程中,一般使用NSLog函数来进行一些打印的工作,这大致相当于C语言的printf输出语句。
NSLog定义在NSObjCRuntime.h中,如下所示,省略号表示可接收多个参数。NSLog使用起来和printf很相似,都是格式化的输出一段文字,不同的是printf需要的格式化字符串是char *类型,而NSLog需要的字符串是NSString型。
当使用NSLog()打印变量时,会根据需要打印变量的类型提供相应的格式化占位符,常用的占位符如下所示。
- %@:对象;
- %d,%i:整数;
- %u:无符整形;
- %f:浮点/双字;
- %x,%X:二进制整数;
- %o:八进制整数;
- %zu:size_t;
- %p:指针;
- %e:浮点/双字(科学计算);
- %g:浮点/双字;
- %s:C字符串;
- %.*s:Pascal字符串;
- %c:字符;
- %C:unichar;
- %lld:64位长整数(long long);
- %llu:无符64位长整数;
- %Lf:64位双字。
6.4.2 定制输入日志的格式
当调用NSLog()来打印调试信息时,默认情况下,系统会按照固定的格式来展示相关的信息。但是在实际的开发过程中,往往希望得到更多、更加详细的信息,因此会涉及对NSLog()函数进行输出日志的定制。
1.默认日志显示格式
在NSLog()中使用%@占位符来打印对象的功能是非常强大的,它不仅可以打印字符串、字典、数组等Foundation框架中已经定义的对象类型,自定义的对象类型也可以使用%@来打印。NSLog配合%@使用时,编译器会自动调用被打印对象的description属性的getter方法,如果打印的是类对象则调用类方法。
在NSObject类中,有一个名为description的属性以及一个名为description的类方法,如下代码所示。
新增一个Person类,并添加几个属性,然后实例化一个Person类对象,并打印对象信息,默认情况下,显示信息如下。
运行结果如图6-21所示。可以看到,打印对象信息时,显示的是对象的类型+内存地址。打印时,显示的是Person。
图6-21 运行结果
2.重写description方法
当希望显示更加个性化的打印信息时,可以重写自定义类的description方法。如下所示,在Person.m中添加如下代码。
当再次运行之前的代码时,打印信息如图6-22所示。
图6-22 运行结果
3.定制NSLog()打印的公共信息
默认情况下,使用NSLog打印出来的日志前面带有很长一串的时间戳,可能有时候根本用不到,而且还会影响查看的效率。其实对于NSLog的输出格式也是可以自定义的,只需要写一个宏定义就可以了。可以把如下宏定义放在程序运行环境中,即可改变NSLog()打印的公共信息,此时,打印的是调用NSLog()函数所在的文件以及行号。
把上述代码添加到main.m中,再次运行,显示信息如图6-23所示。
图6-23 运行结果
由于NSLog的运行效率比较低,所以在项目中非调试状态下(release)不应该出现大量的NSLog,所以有些时候会在项目的.pch文件(或者单独建立一个Macro.h文件管理所有的宏)中去定义一个宏,让调试函数只在调试版本(Debug)中生效,发布版本(Release)中就不能使用。
下方的代码段可以放在项目的宏定义文件中,也可以放在.pch文件中。添加后,打印日志只有在Debug模式下生效,Release模式不打印日志。