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