zoukankan      html  css  js  c++  java
  • Release版本的Log问题

    今天在刷微博的时候,刷到唐巧大大的微博,指出了京东APP的Log没有关闭。如果Log出来的信息值较为重要的话,这可是一个大大的问题哦。
    
    在编写程序的过程中,我们不可避免的要使用`NSLog`来输出一些相关信息来辅助。不过在release版本,这些NSLog语句不会被剔除,仍旧留着我们的程序中。通过`Organizer->MyDevice->Console`我们仍旧可能看到这些输出。  
    当然这并不是我们使用NSLog的初衷,我们只是希望NSLog在debuge阶段能够使用,而在release中不再被使用。  
    以下的代码就是帮助我们做到这一点。
    
    ```
    #ifdef DEBUG
    
    #define DLog( s, ... ) NSLog([NSString stringWithFormat:(s), ##__VA_ARGS__] )
    
    #else
    
    #define DLog( s, ... )
    
    #endif
    ```
    
    ##用DEBUGE判断  
    上面那段代码的逻辑很简单,就是一个if/else的判断  
    
    首先看一下判断的条件是什么?  `#ifdef DEBUG`  
    判断DEBUG是否被define过  
    如果为YES,就定义DLog为封装后的NSLog  
    如果为NO,就将DLog定义为空
    
    那么DEBUG又是如何从哪里来的,又是判断release/debuge状态的呢?
    真相就在`Build Setting`里  
    见下图  
    ![Build Setting](data:image,local://debuge.png)  
    我们可以清楚的看到DEBUG在Debug里面有定义,而在Release中没有定义。  
    这样就能区分release/debuge状态了。
    
    
    
    
    ##DLog
    最开始的代码中,我们用DLog这个宏来替换了系统自带的NSLog。  
    不过DLog只是一个名称,你想叫ELog,FLog,GLog...都是可以的,纯属个人喜好。
    
    DLog中主要由两个点值得我们去思考:  
    * DOLog(s,...)   
    * *## \_\_VA\_ARGS\_\_* 宏  
    
    ###1.DOLog(s,...) 
    我们都知道NSLog中要输出的内容不是固定的,不能知道参数个数,也无法知道参数类型。  
    所以用(s,...)来代表不固定的内容,那么s是什么?...又是什么呢?
    
    我输出了一下下面代码中的s:
    ```
        #define DLog( s, ... ) NSLog([NSString stringWithFormat:(s), ##__VA_ARGS__] )
       
        // 代码
    	int a = 10;
    	DLog(@"a = %d",a);
    	
    	// 输出
    	s: a = %d
    ```
    
    可见,s就代表了我们的格式化字符串@"a = %d",而...就代表了剩余的参数。
    
    ###2.*## \_\_VA\_ARGS\_\_* 宏   
    
    NSLog([NSString stringWithFormat:(s), ##__VA_ARGS__] )  
    这个*## \_\_VA\_ARGS\_\_*到底是是干什么的呢?
    其实*## \_\_VA\_ARGS\_\_*就是代表了省略号
    
    在深究一下,其实*## \_\_VA\_ARGS\_\_*
    其实*## \_\_VA\_ARGS\_\_*拆开成两部分看
    * *##*
    * *\_\_VA\_ARGS\_\_*  
    
    
    *\_\_VA\_ARGS\_\_*是可变参数宏(variadic macros),是一个保留字
    如果我们用*\_\_VA\_ARGS\_\_*来替换*## \_\_VA\_ARGS\_\_*,再运行之前的测试代码,发现一样没问题
    
    不过如果我们修改测试代码为
    ```
        #define DLog( s, ... ) NSLog([NSString stringWithFormat:(s), __VA_ARGS__] )
        // 代码
    	DLog(@"a");
    	
    	// 输出
    	1 error generated.
    ```
    
    这是为什么呢?为什么之前好好的,如果只输出一个字符串就出问题了呢?
    那是因为这段测试代码只有一个字符串,而没有任何可变参数。所以就报错了。那么我们将*\_\_VA\_ARGS\_\_*还原为*## \_\_VA\_ARGS\_\_*后再跑一下这段代码。
    
    成功了。这又是为什么呢?
    这就是*##*的功劳了,##的作用就是防止可变参数为无的情况。
    
    所以我们一定要使用*## \_\_VA\_ARGS\_\_*来代替...
    
    
    参考资料:  
    http://www.cnblogs.com/alexshi/archive/2012/03/09/2388453.html
    
    
  • 相关阅读:
    [设计模式整理笔记 五] 创建者模式(Builder)
    ArrayList与List<T>笔记
    asp.net站点URLRewrite小记
    ArrayList Array List<T>性能比较
    C# Socket SSL通讯笔记
    [设计模式整理笔记 六] 工厂模式与创建者模式总结
    [设计模式整理笔记 七] 原型模式(ProtoType)
    实现页面提交时显示"正在处理.."
    [设计模式整理笔记 四] 抽象工厂模式(Abstract Factory)
    在 ASP.NET 中执行 URL 重写 [转MSDN]
  • 原文地址:https://www.cnblogs.com/peterpan507/p/3592286.html
Copyright © 2011-2022 走看看