1. 程式人生 > >oc之NSlog用法【2】

oc之NSlog用法【2】

原文: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整個檔案裡包含的的其他檔案也會重新編譯一次,這樣就會消耗大量時間,所以它裡面新增的檔案最好是是很少變動或不變動的標頭檔案或者是預編譯的程式碼片段;)檔案中新增
  1. #ifdef DEBUG  
  2. #define NSLog(...) NSLog(__VA_ARGS__)  
  3. #define debugMethod() NSLog(@"%s", __func__)  
  4. #else  
  5. #define NSLog(...)  
  6. #define debugMethod()  
  7. #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或者是對應環境的介面等的設定。