第一个问题是您希望常量具有什么范围,实际上有两个问题:
- 这些常量是否特定于单个类,或者在整个应用程序中使用它们是否有意义?
- 如果它们是特定于类的,它们是供类的客户端使用还是仅在类内部使用?
如果它们是特定且仅在单个类内部使用,请在.m文件顶部声明它们为static const
,如下所示:
static NSString *const MyThingNotificationKey = @"MyThingNotificationKey"
如果它们与单个类有关,但应该是公共的/被其他类使用,请在头文件中声明它们为
extern
,并在.m文件中定义它们:
extern NSString *const MyThingNotificationKey;
NSString *const MyThingNotificationKey = @"MyThingNotificationKey";
如果它们应该是全局的,请在头文件中声明它们并在相应模块中定义它们,专门用于这些常量。
您可以将它们混合使用,以获得不同级别的全局性,对于简单不属于一起的全局常量 - 如果需要,可以将它们放在单独的模块中,每个模块都有自己的头文件。
为什么不使用#define?
旧答案是“宏没有类型信息”,但是现代编译器非常聪明,可以对文本替换(宏扩展)和变量进行所有类型检查。
现代答案是因为调试器不知道您的宏。如果MyThingNotificationKey是一个宏,则无法在调试器命令中说[myThing addObserver:self forKey:MyThingNotificationKey];如果它是一个变量,则调试器只能知道它是一个变量。
为什么不使用枚举?
好吧,在评论中rmaddy比我先回答了:枚举只能定义整数常量。像序列标识符号码、位掩码、四字节代码等内容。
对于这些目的,enum
非常好,您绝对应该使用它。(更好的是,使用NS_ENUM
和NS_OPTIONS
宏。) 对于其他事情,您必须使用其他东西;enum
除了整数之外什么也做不了。
还有其他问题
我在考虑将文件导入Reddit-Prefix.pch文件中,以使常量对所有文件都可用。 这样做好吗?
可能是无害的,但可能过度了。 在需要它们的地方导入您的常量头文件。
每种解决方案的用例是什么?
#define
:功能有限。老实说,我不确定现在还有什么好的理由用它来定义常量。
const
:最适合用于本地常量。此外,如果您在头文件中声明了一个常量并且现在正在定义它,则必须使用此选项。
static const
:最适合用于特定于文件(或类)的常量。
extern const
:在头文件中导出常量时必须使用此选项。
另外,如果使用 extern const
,我需要导入文件吗?还是常量可以全局使用而无需导入文件?
您需要导入文件,可以在每个使用它的文件中导入,也可以在前缀头文件中导入。
enum
只适用于整数值。#define
和常量可以是任何数据类型。 - rmaddyconst
,static const
和extern const
除了作用域之外都是相同的。因此实际上只有三种选择。 - rmaddy