一、多用常量,少用#define預處理指令
const關鍵字,它限定一個變量不允許被改變。使用const在一定程度上可以提高程序的安全性和可靠性。便于進行類型檢查,使編譯器對處理內容有更多了解,消除了一些隱患。
const 推出的初始目的,正是為了取代#define預處理指令,消除它的缺點,同時繼承它的優點。使用#define預處理指令,只是在預處理器里進行文本替換,這樣定義出來的常量不含類型信息,編譯器只是會在編譯前據此執行查找和替換,即時有人重新定義此常量值,編譯器也不會警告,這將導致應用內常量值不一致。
(1) 編譯器處理方式不同
define宏是在預處理階段展開。
const常量是編譯運行階段使用。
(2) 類型和安全檢查不同
define宏沒有類型,不做任何類型檢查,僅僅是展開。
const常量有具體的類型,在編譯階段會執行類型檢查。
(3) 存儲方式不同
define宏僅僅是展開,有多少地方使用,就展開多少次,不會分配內存。(宏定義不分配內存,變量定義分配內存。)如果是字符串類型,取的時候只需要給前面地址,如果是整形、浮點型會有多份拷貝,但這些數寫在指令中。占的只是代碼段而已,大量用宏會導致二進制文件變大
const常量會在內存中分配(可以是堆中也可以是棧中)。共享一塊內存空間,就算項目中N處用到,也不會分配N塊內存空間。
(4)const 可以節省空間,避免不必要的內存分配。
二、const的使用
1、注意常量名稱
static const NSTimeInterval kAninationDuration = 0.3
若常量局限于某“編譯單元”(translation unit,也就是“實現文件”implementation file)之內,則在前面加上字母k;
若常量在類之外可見,則通常以類名為前綴。
2、變量一定要同時用static和const來聲明。如果試圖修改有const修飾的變量,那么編譯器就會報錯。而static修飾符則意味著該變量僅在定義變量的編譯單元可見。編譯器每收到一個編譯單元,就會輸出一份“目標文件”(object file)。那么如果聲明上述變量不加static修飾,則編譯器會為他創建一個“外部符號”(external symbol)。此時若是另一個編譯單元也聲明了同名變量,那么編譯器就會報錯。
實際上,如果變量既聲明為static又聲明為const,那么編譯器根本不會創建符號,而是會像#define預處理指令一樣,把所有遇到的變量都替換成常值。不過這種定義方法的常量帶有類型信息。
那么有時候如果需要公開常量的時候。那么此類常量需要放在“全局符號表”(global symbol table)中,以便可以在定義該常量的編譯單元之外使用。
// In the header file
extern NSString *const XYZStringConstant;
//In the implementation file
NSString *const XYZStringConstant = @"VALUE";
這個變量聲明在頭文件,且在實現文件“定義”。注意const修飾符在常量類型中的位置。常量定義應該從右至左閱讀,所以,EOCStringConstant就是“一個常量,而這個常量是指針,只想NSString對象”,這與需求相符。
3、注意const修飾符在常量類型中的位置。
const只修飾它右邊的內容,被const修飾的內容都是常量