在Objective-C中创建常量的最佳方法是什么
我正在创建一个用于学习目的的Reddit客户端。我需要一个包含常量的文件。我正在考虑在在Objective-C中创建常量的最佳方法是什么,objective-c,constants,Objective C,Constants,我正在创建一个用于学习目的的Reddit客户端。我需要一个包含常量的文件。我正在考虑在Reddit Prefix.pch文件中导入该文件,以使常量可用于所有文件这是一种很好的做事方式吗?另外,我做了研究,发现了几种创建常量的方法,但我不知道该使用哪种方法: #定义宏 const 静态常数 extern const enum 那么哪种方式是首选方式?惯例是什么?我知道“这取决于”但我更具体的问题是:这些解决方案的用例是什么? 另外,如果使用extern const,是否需要导入文件,或者常量将
Reddit Prefix.pch
文件中导入该文件,以使常量可用于所有文件这是一种很好的做事方式吗?另外,我做了研究,发现了几种创建常量的方法,但我不知道该使用哪种方法:
宏#定义
const
静态常数
extern const
enum
extern const
,是否需要导入文件,或者常量将在不导入文件的情况下全局可用
从逻辑上讲,我可以得出这样的结论:
enum
是定义自定义错误域之类的内容时的最佳选择(我说得对吗?)。但是其他的呢?第一个问题是您希望常量具有什么范围,这实际上是两个问题:
- 这些常量是特定于单个类的,还是将它们放在整个应用程序中有意义
- 如果它们是特定于类的,那么它们是供类的客户端使用,还是仅在类内使用
static const
,如下所示:
static NSString *const MyThingNotificationKey = @"MyThingNotificationKey";
如果它们属于单个类,但应为公共类/由其他类使用,请在标题中将它们声明为extern
,并在.m中定义它们:
//.h
extern NSString *const MyThingNotificationKey;
//.m
NSString *const MyThingNotificationKey = @"MyThingNotificationKey";
如果它们应该是全局的,则在头中声明它们,并在相应的模块中定义它们,特别是针对这些常量
您可以将不同的常数与您希望它们具有的不同全局级别进行混合和匹配,对于不属于一起的不同全局常数,您可以将它们放在单独的模块中,每个模块都有自己的标题(如果需要)
为什么不定义?
旧的答案是“宏没有类型信息”,但今天的编译器在对文本(宏扩展到的对象)和变量进行所有类型检查方面都非常聪明
现代的答案是,调试器不知道您的宏。如果MyThingNotificationKey
是宏,则不能在调试器命令中说[mythingaddobserver:self-forKey:MyThingNotificationKey]
;调试器只能在它是变量时知道它
为什么不enum
?
嗯,rmaddy在评论中击败了我:enum
只能定义整数常量。比如序列识别号、位掩码、四字节码等
出于这些目的,enum
非常好,您绝对应该使用它。(更好的是,使用。)对于其他东西,你必须使用其他东西<代码>枚举只做整数
以及其他问题
我正在考虑在Reddit-Prefix.pch文件中导入该文件,以使常量可用于所有文件。这是一种好的做事方式吗
可能无害,但可能过量。在需要的位置导入常量标题
每个解决方案的用例是什么
:非常有限。老实说,我不确定是否有足够的理由再将其用于常量#定义
:最适合本地常量。此外,您还必须将其用于您在头中声明并正在定义的一个const
:最适合文件特定(或类特定)常量静态常量
:导出标头中的常量时必须使用此选项extern const
extern const
,是否需要导入文件,或者常量将在不导入文件的情况下全局可用
您需要在使用该文件的每个文件或前缀标题中导入该文件。FOUNDATION\u导出
<>考虑使用< <代码>基础出口导出>代码>比#if defined(__cplusplus)
#define FOUNDATION_EXTERN extern "C"
#else
#define FOUNDATION_EXTERN extern
#endif
#if TARGET_OS_WIN32
#if defined(NSBUILDINGFOUNDATION)
#define FOUNDATION_EXPORT FOUNDATION_EXTERN __declspec(dllexport)
#else
#define FOUNDATION_EXPORT FOUNDATION_EXTERN __declspec(dllimport)
#endif
#define FOUNDATION_IMPORT FOUNDATION_EXTERN __declspec(dllimport)
#else
#define FOUNDATION_EXPORT FOUNDATION_EXTERN
#define FOUNDATION_IMPORT FOUNDATION_EXTERN
#endif
请访问此链接…您的解决方案位于此链接中post@BhavikKama:这是一个比较狭义的问题,对比了两种特定的解决方案。对于-static const、#define、enum,此链接非常有用,它可以很好地解释const
enum
的三种可选方法,它仅对整数值有用#define
和常量可以是任何数据类型。const
、static const
和extern const
除了范围之外都是相同的。所以实际上只有三种选择。为什么不在.h
文件中使用static NSString*const
?@IulianOnofrei:如果它在应用程序而不是框架中,你可以。如果您执行static NSString*const foo=@“foo”代码>,则标头确定字符串是什么,并且在任何地方都必须相同。如果您更改了字符串,并且不同方使用不同版本的标头和不同的字符串,则在运行时字符串将不匹配。在框架中,您希望只提供对符号的访问,并让框架成为该符号真实值的唯一来源,这样每个人都可以从一个位置获得相同的字符串。这就是extern
带给你的。关于#define
s的补充说明:它们不能保证在内存中有相同的地址(取决于它们的声明方式,它们可能会在每次使用时分配一个新实例),因此使用myObject==MyDefine
并不总是像预期的那样工作,但是myObject==MyStaticConst
will。它有意义吗