![iOS开发:从零基础到精通](https://wfqqreader-1252317822.image.myqcloud.com/cover/796/26793796/b_26793796.jpg)
6.4 NSLog()函数
6.4.1 NSLog()函数基本使用
在编程的过程中,每完成一个功能时都需要进行调试来验证功能实现是否符合预期,而调试过程中打印日志是必不可少的手段之一。通过打印日志,可以验证程序的输入与输出,继而精确地定位问题的位置。在Objective-C编程中,一般使用NSLog函数来进行一些打印的工作,这大致相当于C语言的printf输出语句。
NSLog定义在NSObjCRuntime.h中,如下所示,省略号表示可接收多个参数。NSLog使用起来和printf很相似,都是格式化的输出一段文字,不同的是printf需要的格式化字符串是char *类型,而NSLog需要的字符串是NSString型。
![](https://epubservercos.yuewen.com/D4B438/15253388904120706/epubprivate/OEBPS/Images/Figure-T165_19468.jpg?sign=1738835027-py6QwHNYfmp0XkeN4VZuwk6rXHQDhVl5-0-e5c47e62af7215ba050b075a0202f117)
当使用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的类方法,如下代码所示。
![](https://epubservercos.yuewen.com/D4B438/15253388904120706/epubprivate/OEBPS/Images/Figure-T166_19554.jpg?sign=1738835027-NOag6WNVGJnwWslYsV69RrQFfI126jiG-0-bf17702f94f9abcc63664a5cede6c055)
新增一个Person类,并添加几个属性,然后实例化一个Person类对象,并打印对象信息,默认情况下,显示信息如下。
![](https://epubservercos.yuewen.com/D4B438/15253388904120706/epubprivate/OEBPS/Images/Figure-T166_82866.jpg?sign=1738835027-vbuSQodWr7szAYm2cOrZ9e6jWGp0HSGn-0-6e46f1df6c8bca499065849db4692344)
运行结果如图6-21所示。可以看到,打印对象信息时,显示的是对象的类型+内存地址。打印时,显示的是Person。
![](https://epubservercos.yuewen.com/D4B438/15253388904120706/epubprivate/OEBPS/Images/Figure-P167_19697.jpg?sign=1738835027-UEJV3MVYuYQG9TaSFWMzd6lQlwdnNlgs-0-6ebc6c50f2d10884766bb31318309c27)
图6-21 运行结果
2.重写description方法
当希望显示更加个性化的打印信息时,可以重写自定义类的description方法。如下所示,在Person.m中添加如下代码。
![](https://epubservercos.yuewen.com/D4B438/15253388904120706/epubprivate/OEBPS/Images/Figure-T167_82868.jpg?sign=1738835027-Ln7hObRaauCZk4lOcCMIBzblNd2YOrvW-0-201875e2df01242dd36197a014463b06)
当再次运行之前的代码时,打印信息如图6-22所示。
![](https://epubservercos.yuewen.com/D4B438/15253388904120706/epubprivate/OEBPS/Images/Figure-P167_19704.jpg?sign=1738835027-ePrXqhiFP93HrcJ7cyj9lcja4M5IAUww-0-74e6d1053260971447f55ed54d022119)
图6-22 运行结果
3.定制NSLog()打印的公共信息
默认情况下,使用NSLog打印出来的日志前面带有很长一串的时间戳,可能有时候根本用不到,而且还会影响查看的效率。其实对于NSLog的输出格式也是可以自定义的,只需要写一个宏定义就可以了。可以把如下宏定义放在程序运行环境中,即可改变NSLog()打印的公共信息,此时,打印的是调用NSLog()函数所在的文件以及行号。
![](https://epubservercos.yuewen.com/D4B438/15253388904120706/epubprivate/OEBPS/Images/Figure-T168_19769.jpg?sign=1738835027-MUk35YTk66iZN1HbHjNPXgAZrlUnZ7hY-0-16e9f2dd66fb775029e12753429122af)
把上述代码添加到main.m中,再次运行,显示信息如图6-23所示。
![](https://epubservercos.yuewen.com/D4B438/15253388904120706/epubprivate/OEBPS/Images/Figure-P168_19771.jpg?sign=1738835027-CHpwQkDCuqgesZ9Lcb5dOS860Tm9juX6-0-acc8abb7663bee3064daa6be95562ba8)
图6-23 运行结果
由于NSLog的运行效率比较低,所以在项目中非调试状态下(release)不应该出现大量的NSLog,所以有些时候会在项目的.pch文件(或者单独建立一个Macro.h文件管理所有的宏)中去定义一个宏,让调试函数只在调试版本(Debug)中生效,发布版本(Release)中就不能使用。
下方的代码段可以放在项目的宏定义文件中,也可以放在.pch文件中。添加后,打印日志只有在Debug模式下生效,Release模式不打印日志。
![](https://epubservercos.yuewen.com/D4B438/15253388904120706/epubprivate/OEBPS/Images/Figure-T168_19775.jpg?sign=1738835027-DNnGxz7OLVrNgaaOdb55RA72roncwnos-0-d69a95fa37bd3bdf87e58db3c7366a2b)