今天再總結一點#define和預處理指令的使用。
預處理過程掃描源代碼,對其進行初步的轉換,產生新的源代碼提供給編譯器。可見預處理過程先於編譯器對源代碼進行處理。
預處理指令是以#開頭的代碼行,#后是指令關鍵字,在關鍵字和#號之間允許存在任意個數的空白字符。正行語句構成了一條預處理指令,該指令醬紫啊編譯器進行編譯之前對源代碼做某些轉換,下面是一些常用的預處理指令,
# 空指令,沒有任何效果
#include 包含一個源代碼文件
#define 定義宏
#undef 取消定義宏
#if 如果條件為真,則編譯下面的代碼
#elif 如果前面的#if不為真,則編譯下面的代碼
#endif 結束一個#if...#elif條件編譯塊
#ifdef 如果已經定義了某個宏,則編譯下面的代碼
#ifndef 如果沒有定義某個宏,則編譯下面的代碼
#error 停止編譯並顯示錯誤信息
最近在看公司自己封裝的sdk的時候,遇到了很多#ifdef和#ifndef,下面我就主要距離來說一說這個預處理指令的靈活使用。比如你現在通過代碼創建了一個Button,
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(0, 0, 100, 40);
[btn setTitle:@"BUTTON" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(btnClicked) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
但是根據新的需求,這個Button暫時不需要顯示在界面上面,這時候不可以將該Button相關的代碼注釋掉,這也不失為一個好方法。但是我更推薦使用預處理指令來進行條件判斷,下面我使用兩種方法來說明,
(1)第一種方法,定義一個具體的宏
#define Debug_ShowButton 0
{
//創建Button對象btn
......//省略若干代碼
#if Debut_ShowButton
//如果需要顯示按鈕,那么將其添加到父視圖中
[self.view addSubview:btn];
#else
//不將其添加到父視圖中
//[self.view addSubview:btn];
#endif
}
這時候如果想顯示該Button對象,那么將#define Debug_ShowButton 1,否則寫為#define Debug_ShowButton 0。
(2)第二種方法,定義一個沒有數值的宏
{
#ifdef Debug_ShowButton
[self.view addSubview:btn];
#endif
}
這段代碼的意思就是如果定義了宏Debug_ShowButton,那么就將btn添加到父視圖,如果沒有定義的話,那么不添加到父視圖。這時候如果我們想要將其添加到父視圖,則在文件的頂部寫上#define Debug_ShowButton,對,這時候我們可以不給這個宏指定對應的值,這個代碼僅僅表示定義一個沒有對應值的宏。
總結:
這兩種方法,我更加推薦第二種,因為一般情況下,我們定義一個有對應數值的宏,是為了在代碼中使用該數值,例如#define kStatusBarHieght 20,這樣我們就可以把kStatusBarHeight作為數值在代碼中使用,而第一種方法定義了有對應值的宏Debug_ShowButton,我們卻沒有在代碼中使用它,這樣是不是有點浪費呢;而使用第二種方法定義一個沒有對應值的宏,它只是一個標識符,看起來簡單點。我個人更加推薦第二種!