預(yù)處理指令是以 #
號開頭的代碼行。#
號必須是該行除了任何空白字符外的第一個字符。#
后是指令關(guān)鍵字咪惠,在關(guān)鍵字和#
號之間允許存在任意個數(shù)的空白字符滞时。整行語句構(gòu)成了一條預(yù)處理指令,該指令將在編譯器進(jìn)行編譯之前對源代碼做某些轉(zhuǎn)換柜候。
# // 空指令,無任何效果
#import “" // 導(dǎo)入一個源代碼文件
#include “” // 包含一個源代碼文件
#define macro // 定義宏
#undef macro // 取消定義宏
#if condition // 條件編譯指令,如果滿足condition,則編譯以下內(nèi)容
#ifdef // 條件編譯指令不脯,如果定義了,則往下編譯
#ifndef // 條件編譯指令海洼,如果沒有定義跨新,則往下編譯
#elif // 如果前面的 #if 不為真,當(dāng)前條件為真坏逢,則往下編譯
#endif // 結(jié)束條件編譯塊
#error // 停止編譯域帐,并顯示錯誤信息,一般用于條件編譯
-
導(dǎo)入/包含文件
#import
跟#include
大部分功能是一樣的是整,但是他處理了重復(fù)引用的問題肖揣,我們在引用文件的時候不用再去自己進(jìn)行重復(fù)引用處理。例如:有 A.h B.h C.h三個頭文件
A.h需要引入B.h 和 C.h, 而B.h也引入C.h 這樣就構(gòu)成了重復(fù)引用浮入,使用#import
就可以避免這種情況龙优。有兩種引入方式,一種使用尖括號
< >
,告訴編譯器在編譯器自帶的或外部庫的頭文件中搜索被包含的頭文件事秀,另一種使用雙引號""
彤断,表示在當(dāng)前被編譯的應(yīng)用程序的源代碼文件中搜索被包含的頭文件,如果找不 到易迹,再搜索編譯器自帶的頭文件宰衙。在OC中應(yīng)盡量少在類的頭文件中引入其他頭文件,如果需要在頭文件中用到引入的頭文件睹欲,首先考慮向前聲明(forward declaring),將引入頭文件的時機(jī)盡量延后供炼,只有在有需要時才引入。
@class YourClass
在這種不需要知道
YourClass
類的全部細(xì)節(jié)窘疮,只需要知道有一個類名叫YourClass
就好的情況下袋哼,使用向前聲明可以減少編譯時間,提高效率闸衫。然而有些協(xié)議涛贯,比如“委托協(xié)議”就需要知道協(xié)議內(nèi)容,這時候不能使用向前聲明蔚出,應(yīng)該考慮在類的擴(kuò)展 class-continuation category 中實(shí)現(xiàn)弟翘,這樣的話需要在實(shí)現(xiàn)文件中引入包含的委托協(xié)議頭文件即可含懊,而不需要將其放在公共頭文件中。
要點(diǎn):
- 除非有必要衅胀,否則不要引入頭文件岔乔,一般來說,應(yīng)在某個類的頭文件中使用向前聲明來提及別的類滚躯,并在實(shí)現(xiàn)文件中引入那些類的頭文件雏门。這樣做可以盡量降低類之間的耦合。
- 有時無法使用向前聲明掸掏,比如要聲明某個類遵循意一項(xiàng)協(xié)議茁影,這種情況下,盡量把該類遵循的某協(xié)議的這條聲明移至 class-continuation category中丧凤。如果不行的話募闲,就把協(xié)議單獨(dú)放在一個頭文件中,然后將其引入愿待。
-
宏定義
用
#define
定義一個宏浩螺,用#undef
取消定義一個宏,宏的定義在編譯時只是簡單的替換#define TEST_MACRO 100 // 定義宏 int array[TEST_MACRO]; // 使用定義的宏 #undef TRST_MACRO // 取消定義宏 #define VALUE1 10 #define VALUE2 20 #define VALUE (VALUE1 + VALUE2)
注意:
定義宏常用大寫字母作為宏名
在定義宏的時候仍侥,后面如果有計(jì)算要出,習(xí)慣于使用括號
宏定義可以定義一個函數(shù) 例如:#define SQUARE(x) (x * x) int square = SQUARE(5);
-
# 運(yùn)算符
#
運(yùn)算符將參數(shù)轉(zhuǎn)換為一個字符串 例如:#define TEST(n) @"SHIT"#n NSLog(@"%@",TEST(ON)); // 此時將ON作為字符串拼接到“SHIT”后面
控制臺輸出為
2017-08-19 15:02:30.165640+0800 VowelMovement[7289:370495] SHITON Program ended with exit code: 0
-
## 運(yùn)算符
##
運(yùn)算符的作用是將出現(xiàn)在其兩側(cè)的參數(shù)合并 例如:#define TEST(x, y, z) x##y##z NSLog(@"%d", TEST(1, 2, 3));
控制臺輸出結(jié)果
2017-08-19 15:08:32.405656+0800 VowelMovement[7336:375139] 123 Program ended with exit code: 0
-
條件編譯指令
#if
指令:檢測跟在制造另關(guān)鍵字后的常量表達(dá)式。如果表達(dá)式為真农渊,則編譯后面的代碼患蹂,知道出現(xiàn)#else
、#elif
或#endif
為止砸紊;否則就不編譯传于。#endif
用于終止#if
預(yù)處理指令#ifdef
和#ifndef
:#ifdefined
等價于#ifdef
;#ifdefined
等價于#ifndef#else
指令用于某個#if指令之后,當(dāng)前面的#if指令的條件不為真時醉顽,就編譯#else后面的代碼沼溜。#endif
指令將中指上面的條件塊。-
#elif
預(yù)處理指令綜合了#else
和#if
指令的作用徽鼎。#ifdef TEST printf("defined TEST"); #else printf("no define"); #endif
Reference:
《Effective Objective-C 2.0 編寫高質(zhì)量iOS與OS X代碼的52個有效方法》