NSLog在项目release版本中的使用注意,NSLog在版本发

2020-03-23 22:11 来源:未知

在iOS开发过程中,我们经常要用到NSLog来打印一些调试信息,而且一般是习惯性的大量使用,在模拟器上运行可能没有感觉到什么,但是在真机上,这些NSLog的输出还是比较消耗系统资源的,而且输出的数据有时也可能会暴露出App中的某些私密数据,所以发布正式版时需要把这些输出全部屏蔽掉。

iOS开发debug跟release版本NSLog屏蔽方法,releasenslog

简单介绍以下几个宏: 1) __VA_ARGS__ 是一个可变参数的宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持)。宏前面加上##的作用在于,当可变参数的个数为0时,这里的##起到把前面多余的","去掉,否则会编译出错。 2) __FILE__ 宏在预编译时会替换成当前的源文件名 3) __LINE__宏在预编译时会替换成当前的行号 4) __FUNCTION__宏在预编译时会替换成当前的函数名称   1. 在***-Prefix.pch里面添加,  重新定义系统的NSLog,__OPTIMIZE__ 是release 默认会加的宏 #ifndef __OPTIMIZE__  #define NSLog(...) NSLog(__VA_ARGS__)  #else  #define NSLog(...){}  #endif  2.在***-Prefix.pch里面添加  ,直接自己写#define,当release版本的时候把#define 注释掉即可 #define IOS_DEBUG #ifdef IOS_DEBUG  #define NSLog(...) NSLog(__VA_ARGS__)  #endif  3.在***-Prefix.pch里面添加 #ifdef DEBUG    # define DLog(format, ...) NSLog((@"[文件名:%s]" "[函数名:%s]" "[行号:%d]" format), __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__);    #else    # define DLog(...);    #endif    这种方式需要修改项目的配置,使得在debug编译的时候,编译DLog的宏,产生详细的日志信息,而release的时候,不产生任何控制台输出 相比而言,还是第一种比较方便

简单介绍以下几个宏:1)__VA_ARGS__是一个可变参数的宏,这个可变参数的宏是新的C99规范中新...

在iOS开发过程中,我们经常要用到NSLog来打印一些调试信息,但是其实这些打印还是很消耗系统资源的,有一个笨办法就是每次调试完就把NSLog注释,可是这也太浪费时间了,因为有可能你下次调试还要用到此NSLog.想要完美的解决这个问题有两个方法,在此说一个用的比较多的,楼主之前也是一直在用此方法,但是最近在使用的时候遇见了些坑,也算是愚蠢之极,特此记录下:

我们可以在发release包之前将这些NSLog统统注释掉,但是如果是大量使用,就有些太过麻烦,而且下次开发时,又需要将注释分别打开继续使用,这样做着实无趣。下面列举两种较为优雅的方式解决:

其实就是通过DEBUG条件编译全局控制,先上代码:

因为是全局控制,首先创建pch文件,具体方法较为简单,不过在Xcode6之后注意绑定pch文件的相对路径,这里不再赘述。创建好之后,在pch文件中添加下列代码:

//如果有Debug这个宏的话,就允许log输出...可变参数

#ifdef DEBUG  //调试阶段

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

#else //发布阶段

#define NSLog(...)

#endif

#ifdef DEBUG #define DLog NSLog((@"[文件名:%s]n" "[函数名:%s]n" "[行号:%d] n" fmt), __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__); #define DeBugLog NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); #define NSLog NSLog(__VA_ARGS__); #define MyNSLog(FORMAT, ...) fprintf(stderr,"[%s]:[line %d行] %sn",[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);#else #define DLog #define DeBugLog #define NSLog #define MyNSLog(FORMAT, ...)#endif

因为是全局控制,首先创建pch文件,具体方法较为简单,不过在Xcode6之后注意绑定pch文件的相对路径,这里不再赘述。之后把上述代码CV一下,之后是环境配置见下图,通过切换Debug和Release,可以控制当前工程的编译环境,当在release环境下时,pch预编译的NSLog相关函数执行是无效的.

上述代码中详细列举了四种较为常用的NSLog的封装,一些事参考了网友的写法,已做实际验证。

图片 1

补充: 1) VA_ARGS 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持)。宏前面加上##的作用在于,当可变参数的个数为0时,这里的##起到把前面多余的","去掉的作用,否则会编译出错, 你可以试试。 2) FILE 宏在预编译时会替换成当前的源文件名 3) LINE宏在预编译时会替换成当前的行号 4) FUNCTION宏在预编译时会替换成当前的函数名称

图片 2

接下来是DEBUG和release环境的设置:

项目发布时改为Release,NSLog就可以实现不打印了,省去了一个个注释的麻烦,然后搞定解决,如果没有效果,这个时候你可以看看下"Target > Build Settings > Preprocessor Macros > Debug"里的"DEBUG"的值是否为1.看图

  • 1."Target > Build Settings > Preprocessor Macros > Debug" 里有一个"DEBUG=1",这保证了我们的条件编译的"#if"可以编译。如果没有,请自行添加,注意和代码中的#if后面的字段保持一致。

图片 3

图片 4

Debug那一项直接设为YES也是可以的.因为上边代码的判断条件就是DEBUG的值为真,然后执行打印,否则就是Release环境,则不打印.(一般默认的就是YES不用设置,但偏偏楼主就遇到了二班情况).

  • 2.环境配置见下图,通过切换Debug和Release,可以控制当前工程的编译环境,当在release环境下时,pch预编译的NSLog相关函数执行是无效的。

    图片 5图片 6

插一些题外的,有时候我们不想用系统的NSLog,这时我们可以修改代码

这是个人较为偏爱的一种方式,感觉比较灵活。同样在pch文件中添加下面的代码。

//如果有Debug这个宏的话,就允许log输出...可变参数

#ifdef DEBUG  //调试阶段

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

#else //发布阶段

#define ZPLog(...)

#endif

  • 1.首先自定义全局环境条件编译控制字段

效果跟上边的是一样的!

如果为了严谨还可以在pch文件中加如下代码

/** * 工程全局环境控制 * * 0:开发环境 1:发布环境 2:测试环境 */#define MY_PROJECT_GLOBAL_CONTROL 0

//确保在Release下NSlog不打印数据

#ifdef DEBUG

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

#define debugMethod() NSLog(@"%s", __func__)

#else

#define NSLog(...)

#define debugMethod()

#endif

上面的0、1、2看个人习惯,只要分得清楚各种环境就行。具体工程的编译环境当然也不局限于上述三类。在开发或上线时,只要记得修改上述的值以对应于相应的环境就行,当然最好是工程有对应的几个target,这样也就可分别设置,分别使用,不会混淆了。

  • 2.同方法1一样,添加下面的代码:
#if (MY_PROJECT_GLOBAL_CONTROL == 0) #define DLog NSLog((@"[文件名:%s]n" "[函数名:%s]n" "[行号:%d] n" fmt), __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__); #define DeBugLog NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); #define NSLog NSLog(__VA_ARGS__); #define MyNSLog(FORMAT, ...) fprintf(stderr,"[%s]:[line %d行] %sn",[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);#elif (MY_PROJECT_GLOBAL_CONTROL == 1) #define DLog #define DeBugLog #define NSLog #define MyNSLog(FORMAT, ...)#endif

上述省略了测试环境,测试同开发即可。这种方式较1更为灵活。对应的条件编译当然也不仅仅局限于NSLog,还有NSAssert或者是对应环境的接口等的设置。

相关Demo已经上传至GitHub,可自行下载参考。

参考文章:1.在ios iphone编程中使用封装的NSLog来打印调试信息2.IOS开发之NSLog使用技巧3.iOS开发中那些高效常用的宏<推荐>

TAG标签:
版权声明:本文由美高梅网投平台发布于新闻中心,转载请注明出处:NSLog在项目release版本中的使用注意,NSLog在版本发