让我们来聊聊NSLog吧

NSLog,开发中输出日志都会用到它。

它相当于C语言中得printf,java中得System.out.println()。

最常用的就是文字输出、日志输入等。

NSLog定义在NSObjCRuntime.h中,如下所示:

void NSLog(NSString *format,…);

常用示例:

NSLog(@"输出文字");

NSLog(@"第%d名",3);

NSLog(@“%@,%@,%d",@"1",@"2",3);

输出格式:

%@ 对象

%d, %i 整数

%u,%z 无符整形

%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位双字

%hhdBOOL布尔类型


NSLog相比printf有什么好处呢?或者说有什么不同呢?

1、NSLog会自动加上换行符。

2、NSLog在Debug下会写到system.log中。

3、NSLog会自动加上时间和进程信息。

4、NSLog支持%@去打印一个对象类型,当使用%@时,它会给对象发送消息description,如果想要打印类中的关键信息,可通过重载description方法来实现。

5、NSLog完全具备printf的功能,而printf只能打印纯C语言的变量,不能打印OC中的对象。

开发中会经常需要查看view的frame、bounds等信息,因为frame、bounds都是CGRect类型,属于结构体类型。

我们通常打印则需要frame.size.width之类来进行打印,通过拼写NSLog参数进行打印。其实不用这样,苹果已经为我们准备好了相互的转换方法:

这些全部定义在UIGeometry.h中

UIKIT_EXTERN NSString *NSStringFromCGPoint(CGPoint point);

UIKIT_EXTERN NSString *NSStringFromCGVector(CGVector vector);

UIKIT_EXTERN NSString *NSStringFromCGSize(CGSize size);

UIKIT_EXTERN NSString *NSStringFromCGRect(CGRect rect);

UIKIT_EXTERN NSString *NSStringFromCGAffineTransform(CGAffineTransform transform);

UIKIT_EXTERN NSString *NSStringFromUIEdgeInsets(UIEdgeInsets insets);

UIKIT_EXTERN NSString *NSStringFromUIOffset(UIOffset offset);

UIKIT_EXTERN CGPoint CGPointFromString(NSString *string);

UIKIT_EXTERN CGVector CGVectorFromString(NSString *string);

UIKIT_EXTERN CGSize CGSizeFromString(NSString *string);

UIKIT_EXTERN CGRect CGRectFromString(NSString *string);

UIKIT_EXTERN CGAffineTransform CGAffineTransformFromString(NSString *string);

UIKIT_EXTERN UIEdgeInsets UIEdgeInsetsFromString(NSString *string);

UIKIT_EXTERN UIOffset UIOffsetFromString(NSString *string);

例如打印frame只需要NSLog(@“%@“,NSStringFromCGRect(self.view.frame));即可。


综上,既然NSLog使用这么方便,有利于开发,那我们是不是可以放心使用了呢?

错,其实有一个风险需要注意,NSLog会输出时间、进程等相关信息,它会占用时间和设备资源。当使用模拟器进行开发的时候,NSLog占用资源不明显。大量的log信息在真机上会变卡。卡。卡。卡。卡。卡。卡成狗了有没有。

1、最直接的办法就是在release版本中注释掉NSLog。缺点的是开发过程中还需要重新添加。

2、使用宏进行解决:

#ifndef __OPTIMIZE__

#define NSLog(...) NSLog(__VA_ARGS__)

#else

#define NSLog(...) {}

或者

#ifdef DEBUG

#define NSLog(…) NSLog(__VA_ARGS__)

#else

#define NSLog(…)

#endif

由于__OPTIMIZE__只有在release下才会定义,DEBUG只有在debug下才会定义,所以上述宏即可解决我们的问题。记得将这个宏添加在项目的prefix.pch文件中。


如何去掉NSLog打印的时间戳、进程等信息呢?

最简单的,就是修改NSLog宏,我们可以这样修改宏:

#ifdef DEBUG

#define NSLog(FORMAT, ...) fprintf(stderr,"%s\n",[[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);

#else

#define NSLog(...)

#endif

意思就是将NSLog的参数通过fprintf打印出来,例如我们要打印NSLog(@“第%d名”,3),转换后就变为fprintf(stderr,”%s\n”,[[NSString stringWithFormat:@”第%d名”, 3] UTF8String])

如果我们要打印类名和行号,则需要在log中加入__FILE__和__LINE__,例如:

#ifdef DEBUG

#define NSLog(FORMAT, ...) fprintf(stderr,"%s:%d\t%s\n",[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);

#else

#define NSLog(...)

#endif

常用日志工具:

1、自定义NSLog之ZYDEBUG

#define ZYDEBUG (0 == 0)

#if ZYDEBUG

#define ZYLOG(format,...) NSLog(@"[%s][%s][%d]" format, __FILE__, __func__, __LINE__, ##__VA_ARGS__)

#else

#define ZYLOG(format,...) do{}while(0)

#endif

更新如下:

/* 0 is NSLog(); <0 no output; >0 verbose output */

#define ZYDEBUGLEVEL 0

#if (ZYDEBUGLEVEL > 1)

#define ZYLog(formatString,...) NSLog(@"\n\tFile:%@, \n\tFunction:%s, \n\tLine:%d>>" formatString, [[NSString stringWithUTF8String:__FILE__] lastPathComponent] , __func__, __LINE__, ##__VA_ARGS__)

#elif (ZYDEBUGLEVEL == 0)

#define ZYLog(formatString, ...) NSLog(formatString, ##__VA_ARGS__)

#else

#define ZYLog(formatString,...) do{}while(0)

#endif

2、SNLog

3、NSLogger

4、CocoaLumberjack

 

 

打赏

尊重原创内容,转载请注明出处
本文链接地址: https://www.awnlab.com/archives/131

为您推荐

发表评论

邮箱地址不会被公开。 必填项已用*标注