第一个问题是您希望常量具有什么范围,这实际上是两个问题:
- 这些常量是特定于单个类的,还是将它们遍布整个应用程序是否有意义?
- 如果它们是特定于类的,它们是供类的客户使用的,还是只在类内使用?
如果它们是单个类的特定和内部的,请将它们声明为static const
.m 文件的顶部,如下所示:
static NSString *const MyThingNotificationKey = @"MyThingNotificationKey";
如果它们属于单个类但应该是公共的/由其他类使用,extern
请在标题中声明它们并在 .m 中定义它们:
//.h
extern NSString *const MyThingNotificationKey;
//.m
NSString *const MyThingNotificationKey = @"MyThingNotificationKey";
如果它们应该是全局的,则在标头中声明它们并在相应的模块中定义它们,特别是针对那些常量。
您可以将它们混合和匹配用于具有不同全局级别的不同常量,以及根本不属于一起的不同全局常量 - 您可以将它们放在单独的模块中,每个模块都有自己的标题,如果你想。
为什么不#define
呢?
旧的答案是“宏没有类型信息”,但今天的编译器非常聪明地对文字(宏扩展为)以及变量进行所有类型检查。
现代的答案是因为调试器不会知道你的宏。如果是宏,你不能[myThing addObserver:self forKey:MyThingNotificationKey]
在调试器命令中说;MyThingNotificationKey
如果它是一个变量,调试器只能知道它。
为什么不enum
呢?
好吧,rmaddy 在评论中击败了我:enum
只能定义整数常量。诸如序列号、位掩码、四字节代码等之类的东西。
出于这些目的,enum
它很棒,您绝对应该使用它。(更好的是,使用andNS_ENUM
宏NS_OPTIONS
。)对于其他的东西,你必须使用其他的东西;enum
除了整数之外什么都不做。
和其他问题
我正在考虑将文件导入 Reddit-Prefix.pch 文件以使常量可用于所有文件。这是做事的好方法吗?
可能无害,但可能过度。在需要的地方导入常量标头。
每个解决方案的用例是什么?
#define
: 相当有限。老实说,我不确定是否有充分的理由再将其用于常量。
const
: 最适合局部常量。此外,您必须将其用于您在标题中声明并正在定义的内容。
static const
: 最适合文件特定(或类特定)的常量。
extern const
:在标头中导出常量时必须使用它。
另外,如果使用extern const
,我是否需要导入文件,或者常量将在全局范围内可用而无需导入文件?
您需要在使用它的每个文件中或在前缀标头中导入该文件。