原文:http://blog.csdn.net/yu413854285/article/details/38823189
http://www.jianshu.com/p/2e79436e5fe3
前提:在XCode做开发调试时往往需要打印一些调试信息做debug用,大家知道当打印信息的地方多了之后在模拟器上跑可能不会有什么问题,因为模拟器用的是电脑的硬件但是当应用跑在设备上时这些输出语句会在很大程度上影响应用的性能,针对这种问题可以写一些宏来控制这些调试信息的输出。
在release版本禁止输出NSLog内容
因为NSLog的输出还是比较消耗系统资源的,而且输出的数据也可能会暴露出App里的保密数据,所以发布正式版时需要把这些输出全部屏蔽掉。
我们可以在发布版本前先把所有NSLog语句注释掉,等以后要调试时,再取消这些注释,这实在是一件无趣而耗时的事!还好,还有更优雅的解决方法,就是在项目的prefix.pch文件里加入下面一段代码,加入后,NSLog就只在Debug下有输出,Release下不输出了。
如何实现:
在
-Prefix.pch(pch全称是“precompiled header”,也就是预编译头文件,该文件里存放的工程中一些不常被修改的代码,比如常用的框架头文件,这样做的目的提高编译器编译速度。我们知道当我们修改一个工程中某个文件代码时候,编译器并不是重新编译所有所有文件,而是编译改动过文件的,假如pch中某个文件修改了,那么pch整个文件里包含的的其他文件也会重新编译一次,这样就会消耗大量时间,所以它里面添加的文件最好是是很少变动或不变动的头文件或者是预编译的代码片段;)文件中添加
- #ifdef DEBUG
- #define NSLog(...) NSLog(__VA_ARGS__)
- #define debugMethod() NSLog(@"%s", __func__)
- #else
- #define NSLog(...)
- #define debugMethod()
- #endif
上段代码的意思就是 用宏指令做一个判断,如果DEBUG为真,则编译#ifdef到#endif宏定义,否则编译器就不编译;
接下来是DEBUG和release环境的设置:
- 1."Target > Build Settings > Preprocessor Macros > Debug" 里有一个"DEBUG=1",这保证了我们的条件编译的"#if"可以编译。如果没有,请自行添加,注意和代码中的#if后面的字段保持一致。
- 2.环境配置见下图,通过切换Debug和Release,可以控制当前工程的编译环境,当在release环境下时,pch预编译的NSLog相关函数执行是无效的。
2.通过自定义条件编译条件全局控制
这是个人较为偏爱的一种方式,感觉比较灵活。同样在pch文件中添加下面的代码。
- 1.首先自定义全局环境条件编译控制字段
/** * 工程全局环境控制 * * 0:开发环境 1:发布环境 2:测试环境 */ #define MY_PROJECT_GLOBAL_CONTROL 0
上面的0、1、2看个人习惯,只要分得清楚各种环境就行。具体工程的编译环境当然也不局限于上述三类。
在开发或上线时,只要记得修改上述的值以对应于相应的环境就行,当然最好是工程有对应的几个target,这样也就可分别设置,分别使用,不会混淆了。
- 2.同方法1一样,添加下面的代码:
上述省略了测试环境,测试同开发即可。#if (MY_PROJECT_GLOBAL_CONTROL == 0) #define DLog(fmt, ...) NSLog((@"[文件名:%s]\n" "[函数名:%s]\n" "[行号:%d] \n" fmt), __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__); #define DeBugLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); #define NSLog(...) NSLog(__VA_ARGS__); #define MyNSLog(FORMAT, ...) fprintf(stderr,"[%s]:[line %d行] %s\n",[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]); #endif #if (MY_PROJECT_GLOBAL_CONTROL == 1) #define DLog(...) #define DeBugLog(...) #define NSLog(...) #define MyNSLog(FORMAT, ...) nil #endif
这种方式较1更为灵活。对应的条件编译当然也不仅仅局限于NSLog,还有NSAssert或者是对应环境的接口等的设置。