1. 宏的簡單介紹
我在做項目時,發現很多開發者一般會創建一些名爲Constant.h、Public.h的文件,在這些文件中定義大量的宏。有字符串常量、函數、方法等。
- 字符串常量,多是接口名、接口網址、在使用NSUserDefaults時的key等等,這樣做的好處是,當接口網址或接口名變更時,我們只需要更改Constant文件中的宏,項目中對於這些字符串常量一次就能修改完,不會有所遺漏。
- 常用的函數、方法,比如修改顏色的方法
#define RGBA(r, g, b, a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a]
、屏幕尺寸#define screen_width [UIScreen mainScreen].bounds.size.width
等等。
2.PCH的簡單介紹
PCH文件(Precompile Prefix Header File),也就是預編譯頭文件,其作用就是,方便你一次性導入在多個文件中同時用到的頭文件、宏或者URL地址等(全局使用),可以有效的幫你節約時間,提高開發效率。我通常使用PCH引入常用的頭文件,比如上面提到的Constant.h、Public.h,還有一些常用三方SDK頭文件等等。關於PCH,我看到的下面這個網址的教程非常詳細,在這裏就不過多描述了。
3.const與宏的區別
const與宏的區別,從四個方面來記
- 編譯時刻 宏:預編譯; const:編譯
- 編譯檢查 宏:沒有編譯檢查; const:有編譯檢查
- 宏的好處 宏:可以定義函數、方法; const:不行
- 宏的壞處 宏:大量使用宏,會導致預編譯時間過長
首先,解釋下預編譯,項目編譯時,如下圖所示,會有個藍色的進度條,這就是在預編譯。如果使用過多的宏,這個進度條就會異常緩慢。
編譯檢查,如下圖所示,宏不會編譯檢查,而const會編譯檢查
很多Blog都說使用宏,會消耗很多內存 , 宏定義的是常量,常量都放在常量區,只會生成一份內存。我通過下面的代碼驗證並不會消耗很多內存。如下圖所示,使用同一個宏,地址都是相同的。而且,定義完宏都是直接用的,我想沒有人會先定義個變量,將宏賦值給變量,再去用變量吧,這樣倒是會消耗許多內存……關於這裏還有一點,我感覺那些Blog想表達的意思是,大量使用宏,會導致預編譯時間過長……
4.const的使用
const的作用:
- 修飾const右邊的基本變量(
int a
)或者指針變量(int *a
)- 被const修飾的變量是隻讀的
// const右邊修飾的是str1,str1是隻讀的,但是*str1可以修改
NSString * const str1 = @"str1";
// const右邊修飾的是*str2,*str2是隻讀的,但是str2可以修改
NSString const *str2 = @"str2";
const使用場景
- 修飾全局變量
- 修飾方法中的參數
蘋果官方推薦用const定義全局變量,而不是使用宏。定義全局變量使用const的意義在於,定義一些key時(比如在NSUserDefaults中使用的key),我們不想讓key隨意修改(在存值時用的key,未取值時先修改了key,結果key取不到值)。
// 蘋果官方不推薦使用宏
// #define nameKey @"nameKey"
// 推薦使用const,const修飾的nameKey是隻讀的,不能修改
NSString * const nameKey = @"nameKey";
- (void)test:(int const *)a
{
// 在方法中不想修改參數,添加const修飾符就無法修改了
*a = 1;
}
const與static聯合使用
const用來修飾全局變量,使全局變量只讀。 而static修飾全局變量,修改全局變量的作用域。我們定義一個全局變量來替代宏,但是我們希望這個全局變量僅僅作用在當前文件夾下,這時候就需要static來修飾了。
static NSString * const key = @"key";
const與extern聯合使用
通常,我們需要將全局變量全部定義在同一個文件下使用,這樣的好處在於方便管理,假如出現全局變量重名的情況,會直接報錯,方便查找錯誤。
extern可以置於變量或者函數前,以表示變量或者函數的定義在別的文件中,提示編譯器遇到此變量和函數時在其他模塊中尋找其定義。
// xx.h 文件中實現聲明
extern NSString * const key;
// xx.m 文件中實現賦值
NSString * const key = @"lemontree";