美文网首页iOS开发实录iOS自学之路iOS技能收集
iOS NSLog在项目release版本中的使用注意

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

作者: 霖溦 | 来源:发表于2016-02-01 14:51 被阅读5519次

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

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

    1.通过DEBUG条件编译全局控制

    因为是全局控制,首先创建pch文件,具体方法较为简单,不过在Xcode6之后注意绑定pch文件的相对路径,这里不再赘述。
    创建好之后,在pch文件中添加下列代码:
    #ifdef DEBUG
    #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]);
    #else
    #define DLog(...)
    #define DeBugLog(...)
    #define NSLog(...)
    #define MyNSLog(FORMAT, ...)
    #endif
    上述代码中详细列举了四种较为常用的NSLog的封装,一些事参考了网友的写法,已做实际验证。

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

    接下来是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]);
      #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开发中那些高效常用的宏<推荐>

    ·转载请注明出处·

    相关文章

      网友评论

      • 强力黑手:楼主,我想确认一下。你的意思就是,把build configuration里面的debug改成release。在发布版本的app就不会运行了。是不是这个意思?因为我发现我发布到手机上的时候,我的project里的output还是有输出(如果不是这样,应该是我写的可能有问题)。请回复,谢谢
        强力黑手:我找到我的原因了,设置里面没有配置。:joy: ,需要在build setting里面把prefix header设置一下。要不然不起作用。PS:我是小白
      • tanpengsccd:这个 貌似有比较好的DDLog 三方日志库。
        #if
        #elif
        #end
        这样更合理吧
        霖溦:@tanpengsccd 嗯,是的,这里只是示例,实际开发有可能有三个以上的环境,会写多个分支。这个是早前写的,实际开发中,能够用接口动态控制日志打印,并自动回传,对于线上环境,才是最有用的。
      • 被吹落的风:您好,我添加上后,怎么连测试环境都不打印了
        霖溦:@Vine_Finer 你是用DEBUG控制的?那就不清楚了,因为我都是手写宏配置,DEBUG用起来就怕忘记修改。。。手写宏配置和系统版本无关了。不过NSLog在xcode8之后一直存在bug,打印不全,至今无解,所以更换了printf,至少打印信息是全的
        Vine_Finer:@被吹落的风 xcode 8.1有调整
        霖溦:@被吹落的风 看你怎么搞的了,我一直在用没问题,你检查下你的条件判定
      • ryugaku:学到了
      • 95bb1f8adaf4:这个好,今天经理也刚刚跟我说了这个,不过没明白具体怎么做,新手,刚好看到具体流程,学习了,哈哈
      • Theyouth:好东西收藏了
      • 031a00324437:不错,不过习惯性的再用过之后就给注释了
        霖溦:@噤址 谢谢~
        031a00324437:@霖溦 嗯 所以我收藏了 这个还是很好的
        霖溦:@噤址 嗯,好习惯,不过有些每次都需要参考的log信息还是要保留的,用这种方式还是能在一定程度上提高效率的。
      • 爱生活爱康康:加油,期待你更好的作品
        霖溦:@爱生活爱康哥 好哒
      • 杯凉茶:楼主写的不错,:+1:学习了!
        霖溦:@杯凉茶 谢谢回复,共勉

      本文标题:iOS NSLog在项目release版本中的使用注意

      本文链接:https://www.haomeiwen.com/subject/xoyskttx.html