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
    
    
  • 相关阅读:
    iot 表索引dump《2》
    heap表和iot表排序规则不同
    Cannot complete the install because one or more required items could not be found.
    iot表输出按主键列排序,heap表不是
    iot 表主键存放所有数据,且按数据插入顺序排序
    iot表和heap表排序规则不同
    org.eclipse.graphiti.ui.editor.DiagramEditorInput.
    Oracle 排序规则
    perl 异步超时 打印错误
    14.6.3 Grouping DML Operations with Transactions 组DML操作
  • 原文地址:https://www.cnblogs.com/peterpan507/p/3592286.html
Copyright © 2011-2022 走看看