Objective-C或者C語言中在定義常量時,有一個大家都比較習慣的方式,就是用預處理的巨集定義常量,比如
#define kAnimationTime 3
複製程式碼
這麼寫有個明顯的問題就是缺乏型別資訊,在標頭檔案引入時,由於是預編譯的指令,常量名稱也可能出現衝突。此時可以使用型別常量來解決這個問題。
static const NSTimeInterval kAnimationTime = 3;
複製程式碼
在實現檔案內部,可以用這種方式代替#define
指令。
const
表示kAnimationTime是一個常量,不可修改。static
表示僅在實現檔案內部可見,因為oc以一個.m
檔案為編譯單元,static
標記的常量僅在當前編譯單元生效,如果不加static
關鍵字,編譯器會為kAnimationTime建立一個外部符號,此時,如果其他類有常量名重複,編譯器將會報錯。NSTimeInterval
就是當前常量的型別。
所以,外部需要引用常量時,並不需要static
關鍵字,?如下:
///標頭檔案中
extern NSString *const KKLLoginNotification;
///實現檔案中
NSString *const KKLLoginNotification = @"KKLLoginNotification"
複製程式碼
- 實現檔案中宣告KKLLoginNotification常量,並且建立了外部符號
extern
表示將KKLLoginNotification寫入全域性符號表,這樣編譯器不需要知道KKLLoginNotification的具體定義,只要知道全域性符號表中有KKLLoginNotification,就會允許程式碼使用KKLLoginNotification。
事實上,這也是UIKit等iOS SDK中定義通知所常用的方式。
最後補充一下常量的命名原則:
static
標記的常量只在當前編譯目標中有效,所以不存在衝突風險,可以新增k
為字首標記,如kAnimationTime
。- 寫入外部符號表的常量和其他常量存在名字衝突的風險,全域性都要使用的,建議新增全域性統一的字首,個別類使用的,並和當前類相關的常量,建議在統一字首後在新增對應的類名,比如
EOCLoginManagerDidLoginNotification