iOS開發:NSLog使用技巧

前提:在XCode做開發調試時往往需要打印一些調試信息做debug用,大家知道當打印信息的地方多了之後在模擬器上跑可能不會有什麼問題,因爲模擬器用的是電腦的硬件但是當應用跑在設備上時這些輸出語句會在很大程度上影響應用的性能,針對這種問題可以寫一些宏來控制這些調試信息的輸出。


在release版本禁止輸出NSLog內容

因爲NSLog的輸出還是比較消耗系統資源的,而且輸出的數據也可能會暴露出App裏的保密數據,所以發佈正式版時需要把這些輸出全部屏蔽掉。

我們可以在發佈版本前先把所有NSLog語句註釋掉,等以後要調試時,再取消這些註釋,這實在是一件無趣而耗時的事!還好,還有更優雅的解決方法,就是在項目的prefix.pch文件里加入下面一段代碼,加入後,NSLog就只在Debug下有輸出,Release下不輸出了。


如何實現:

-Prefix.pch(pch全稱是“precompiled header”,也就是預編譯頭文件,該文件裏存放的工程中一些不常被修改的代碼,比如常用的框架頭文件,這樣做的目的提高編譯器編譯速度。我們知道當我們修改一個工程中某個文件代碼時候,編譯器並不是重新編譯所有所有文件,而是編譯改動過文件的,假如pch中某個文件修改了,那麼pch整個文件裏包含的的其他文件也會重新編譯一次,這樣就會消耗大量時間,所以它裏面添加的文件最好是是很少變動或不變動的頭文件或者是預編譯的代碼片段;)文件中添加
[plain] view plaincopy
  1. #ifdef DEBUG  
  2. #define NSLog(fmt,...) do{NSLog(fmt,##__VA_ARGS__);} while(0)
  3. #define debugMethod() NSLog(@"%s", __func__)  
  4. #else  
  5. #define NSLog(...)  do{}while(0)
  6. #define debugMethod()  
  7. #endif  
其他的各種例子:
<a target=_blank target="_blank" id="L1" href="https://code.csdn.net/dashboard/snippets#L1" rel="#L1" style="color: rgb(102, 102, 102); text-decoration: none;">  1</a>
<a target=_blank target="_blank" id="L2" href="https://code.csdn.net/dashboard/snippets#L2" rel="#L2" style="color: rgb(102, 102, 102); text-decoration: none;">  2</a>
<a target=_blank target="_blank" id="L3" href="https://code.csdn.net/dashboard/snippets#L3" rel="#L3" style="color: rgb(102, 102, 102); text-decoration: none;">  3</a>
<a target=_blank target="_blank" id="L4" href="https://code.csdn.net/dashboard/snippets#L4" rel="#L4" style="color: rgb(102, 102, 102); text-decoration: none;">  4</a>
<a target=_blank target="_blank" id="L5" href="https://code.csdn.net/dashboard/snippets#L5" rel="#L5" style="color: rgb(102, 102, 102); text-decoration: none;">  5</a>
<a target=_blank target="_blank" id="L6" href="https://code.csdn.net/dashboard/snippets#L6" rel="#L6" style="color: rgb(102, 102, 102); text-decoration: none;">  6</a>
<a target=_blank target="_blank" id="L7" href="https://code.csdn.net/dashboard/snippets#L7" rel="#L7" style="color: rgb(102, 102, 102); text-decoration: none;">  7</a>
<a target=_blank target="_blank" id="L8" href="https://code.csdn.net/dashboard/snippets#L8" rel="#L8" style="color: rgb(102, 102, 102); text-decoration: none;">  8</a>
<a target=_blank target="_blank" id="L9" href="https://code.csdn.net/dashboard/snippets#L9" rel="#L9" style="color: rgb(102, 102, 102); text-decoration: none;">  9</a>
<a target=_blank target="_blank" id="L10" href="https://code.csdn.net/dashboard/snippets#L10" rel="#L10" style="color: rgb(102, 102, 102); text-decoration: none;"> 10</a>
<a target=_blank target="_blank" id="L11" href="https://code.csdn.net/dashboard/snippets#L11" rel="#L11" style="color: rgb(102, 102, 102); text-decoration: none;"> 11</a>
<a target=_blank target="_blank" id="L12" href="https://code.csdn.net/dashboard/snippets#L12" rel="#L12" style="color: rgb(102, 102, 102); text-decoration: none;"> 12</a>
<a target=_blank target="_blank" id="L13" href="https://code.csdn.net/dashboard/snippets#L13" rel="#L13" style="color: rgb(102, 102, 102); text-decoration: none;"> 13</a>
<a target=_blank target="_blank" id="L14" href="https://code.csdn.net/dashboard/snippets#L14" rel="#L14" style="color: rgb(102, 102, 102); text-decoration: none;"> 14</a>
<a target=_blank target="_blank" id="L15" href="https://code.csdn.net/dashboard/snippets#L15" rel="#L15" style="color: rgb(102, 102, 102); text-decoration: none;"> 15</a>
<a target=_blank target="_blank" id="L16" href="https://code.csdn.net/dashboard/snippets#L16" rel="#L16" style="color: rgb(102, 102, 102); text-decoration: none;"> 16</a>
//DLog will output like NSLog only when the DEBUG variable is set
#ifdef DEBUG
#define DLog(fmt, ...) do{ NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);}while(0)
#else
#define DLog(...) do{}while(0)
#endif
// ALog will always output like NSLog
#define ALog(fmt, ...) do{NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);}while(0)
// ULog will show the UIAlertView only when the DEBUG variable is set
#ifdef DEBUG
#define ULog(fmt, ...) do{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"%s\n [Line %d] ", __PRETTY_FUNCTION__, __LINE__] message:[NSString stringWithFormat:fmt, ##__VA_ARGS__] delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alert show]; }while(0)
#else
#define ULog(...) do{}while(0)
#endif

上段代碼的意思就是 用宏指令做一個判斷,如果DEBUG爲真,則編譯#ifdef到#endif宏定義,否則編譯器就不編譯;



這個DEBUG在哪設置呢,

在 "Target > Build Settings > Preprocessor Macros > Debug" 裏有一個"DEBUG=1"。

設置爲Debug模式下,Product-->Scheme-->SchemeEdit Scheme
設置Build Configuration成Debug時,就可以打印NSLog了。
設置Release,發佈app版本的時候就不會打印了,提高了性能

附加知識:
文中提到的幾個宏這裏再簡單解釋一下:
[1]__VA_ARGS__是一個可變參數的宏,這個可變參數的宏是新的C99規範中新增的,目前似乎只有GCC支持(VC6.0編譯器不支持)。宏前面加上##的作用在於,當可變參數的個數爲0時,這裏的##起到把前面多餘的","去掉,否則會編譯出錯。
[2]__FILE__宏在預編譯時會替換成當前的源文件名
[3]__LINE__宏在預編譯時會替換成當前的行號
[4]__FUNCTION__宏在預編譯時會替換成當前的函數名稱

另外也可以使用下面的方法來重寫系統的NSLog
#ifndef __OPTIMIZE__//__OPTIMIZE__是release默認會加的宏
#define NSLog(fmt,...)   do{NSLog(fmt,##_VA_ARGS__);}while(0)
#else
#define NSLog(fmt,...)   do{}while(0)
#endif
或者寫成:
#ifndef DEBUG//這裏必須在 "Target > Build Settings > Preprocessor Macros > Debug" 裏設置"DEBUG=1"。(因爲有的情況下,這個設置爲空,需手動設置。如Unity3D生成的Xcode代碼默認就沒有設置)

#ifdef DEBUG

    #define NSLog(format, ...)  do{                                                                             \

                                    fprintf(stderr,"<%s : %d> %s\n",                                           \

                                    [[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String],  \

                                    __LINE__, __func__);                                                        \

                                    (NSLog)((format), ##__VA_ARGS__);                                           \

                                    fprintf(stderr,"-------\n");                                               \

                                } while (0)

#else

    #define NSLog(format, ...)  do{}while(0)//release模式下,忽略

#endif

發佈了19 篇原創文章 · 獲贊 16 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章