【OC梳理】預處理指令

預處理指令,就是我們常說的宏定義。在編譯器對 C或者 objective-c 進行編譯前,編譯器會對這些預處理命令進行處理,在編譯源程序時,會將定義的內容進行替換編譯。
正確地使用預處理可以簡化代碼、提高代碼的可讀性和編寫效率。

使用#define及#undef 執行宏定義

這里#define的作用是為后面的語句起一個別稱,可以使用有意義的名字代替,可以簡化編寫過程,提高程序可讀性。例:

//將一些常量值定義成有意義的名稱,可以提高程序可讀性
//實際項目開發中,常把一些未來可能需要修改的值定義成宏,這樣可以避免批量更改代碼中的值
#define PI  3.14159
//將獲取屏幕寬度的代碼定義成宏,可以簡化代碼,提升編寫效率
#define KScreenWidth        ([[UIScreen mainScreen] bounds].size.width)

需要注意的是

宏定義不是C 語句。無需用分號結束,也不要使用=進行賦值。
宏定義不是變量。不要對宏名稱進行賦值。
編譯器處理宏定義,只是進行”查找,替換”,要保證宏定義是正確的。
執行宏定義后,該宏的作用 域為定義該宏開始,直到該源代碼結束,如果想提前結束宏定義,可以使用語句:#undef 宏名稱

帶參數的宏定義

可以在宏定義中使用參數,這樣定義的宏更靈活。 格式為:

#define 宏名稱(參數列表) 字符串

例如,將UIColor的創建進行紅定義,可以大大簡化設置顏色的過程:

//RGB色值
#define RGB(r,g,b)          [UIColor colorWithRed:r/255. green:g/255. blue:b/255. alpha:1.]
#define RGBA(r,g,b,a)       [UIColor colorWithRed:r/255. green:g/255. blue:b/255. alpha:a]
//十六進制顏色
#define HEXCOLOR(str)       [UIColor hexFloatColor:str]

需要注意的是

因為宏定義只是執行簡單查找和替換,當傳入的參數是個表達式的時候,常會出現一些我們不希望出現的錯誤。所以,為了編譯器能正確處理宏定義,建議將宏定義中的參數用圓括號括起來。如果整個宏定義返回的是數值,可再將整個宏定義的字符串用圓括號括起來。

使用#ifdef,#ifndef,#else,#endif 執行條件編譯

有時候需要選擇性編譯——比如對于特定的設備,只編譯該設備相關的代碼,就可以借助條件編譯來完成。
語法格式1:

//已定義某個宏,則執行
#ifdef  宏名稱
  //任意語句
#endif

//如果未定義某個宏,則執行
#ifndef  宏名稱
//任意語句
#endif

根據是否定義了指定的宏,選擇執行
語法格式2:

//已定義某個宏
#ifdef  宏名稱
  //任意語句
#else 
  //任意語句
#endif

//如果未定義某個宏
#ifndef  宏名稱
    //任意語句
#else 
    //任意語句
#endif

其使用過程類比平常代碼中使用的if...else...
通過條件編譯語句,可以較方便地自適應不同的設備。
通過判斷是否debug模式來輸出,例:

//DEBUG  模式下打印日志,當前行
#ifdef DEBUG
#define GZCLog(fmt,...)     NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ## __VA_ARGS__);
#define GZCPrint(...)       printf(__VA_ARGS__)
#else
#define GZCLog(...)
#define GZCPrint(...)
#endif

使用#if,#elif,#else,#endif 進行條件編譯

對表達式進行判斷,根據表達式的值決定是否要編譯指定的語句。
語法格式:

#if  表達式
  //任意語句
#elif  表達式
  ...// 可以有零到多個#elif 語句
#else
  //任意語句
#endif

條件編譯語句和流程控制語句有何區別?

使用條件編譯指令時,不符合條件的程序語句根本不會編譯;
使用普通的分支語句時,所有的代碼都被編譯成執行性代碼,程序運行時再根據需要決定執行哪些語句。
這就意味著條件編譯語句生成的文件更小,執行效率更高。

#include 與#import

和C語言相同,#include 指令的作用很簡單:將指定的源碼插入到當前代碼的制定位置。但有個顯著的缺點,需要程序員自行判斷是否重復導入。但#import可以幫助判斷,避免重復導入的問題。
OC中,#import 中引號和尖括號的作用:

雙引號,告訴預處理程序到當前文件所在路徑搜索指定的源文件(也可通過 Xcode 的項目設置來設置預處理的搜索路徑);
而尖括號<>,告訴預處理程序到相應的系統頭文件路徑中搜索。

以上就是常用的預處理指令。
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容