#define ANIMATION_DURATION 0.3
缺点:
1)这样定义没有类型信息,使阅读代码的人难以理解其意图。
2)假设此指令声明在了某个头文件中,那么所有引入这个头文件的代码,其ANIMATION_DURATION都会背替换为0.3。
更好的定义方式:
static const NSTimeInterval kAnimationDuration = 0.3;
优点:
1)包含类型信息NSTimeInterval,更清楚的描述了常量的含义。
2)避免了常量命名发生冲突。
注意:
1)常量的定义不应该出现在头文件中,放在头文件等于声明了一个名叫kAnimationDuration的全局变量,如果要放在头文件中也应该以类名为前缀命名。
2)使用const来声明,如果试图修改由const声明的变量那么编译器就会报错。我们更希望我们所定义的动画播放时长不应该被修改。
3)使用static来声明,static修饰的变量具有文件作用域,防止其他文件声明了同名的变量导致编译器抛出错误信息。
对外公开某个常量的定义方式
//in the header file
extern NSString * const StringConstant;
//in the implementation file
NSString * const StringConstant = @"VALUE";
使用const修饰指针常量是因为我们不希望有人改变此指针常量指向另一个NSString对象,使用extern声明是告诉编译器,在全局符号表中有一个名字叫StringConstant的符号,也就是说编译器无需查看其定义,即允许代码使用此常量,但需要注意命名以防止冲突,通常以类名为前缀。
对比预处理指令优点:编译器会确保常量的值不变,一旦在实现文件中定义好,即可随处使用。而采取预处理指令所定义的常量可能会无意中遭人修改,从而导致应用程序各个部分所使用的值不同。
总结:
1)不要用预处理指令定义常量,这样定义出来的常量不含类型信息,编译器只是会在编译前据此执行查找与替换操作。即使有人重新定义了常量的值,编译器也不会产生警告信息,这将导致应用程序中的常量值不一致。
2)在实现文件中使用static const来定义“只在编译单元内可见的常量”。由于此类常量不在全局符号表中,所以无需为其名称加前缀。
3)在头文件中使用extern来声明全局常量,并在相关实现文件中定义其值。这种常量要出现在全局符号表中,所以其名称应加以区隔,通常用与之相关的类名做前缀。