我之前已经问过这个问题,但我似乎无法在Apple的文档中找到有关它的信息;也许你们有些人做过。
许多Objective-C代码使用.h
在#define
文件中具有跨文件常量。
其他人在.m
文件中使用extern
方法和常量.h
方法。
我理解差异,包括优点和缺点,但Apple是否说明在iOS开发中使用哪一个?
答案 0 :(得分:22)
在extern上使用#defines的麻烦在于编译器无法进行任何类型检查。如果你#define一个字符串,没有什么可以阻止你在你想要的地方使用它,比如一个数字。如果您使用静态NSString,如果您尝试在不期望字符串的地方使用它,编译器将发出警告。
答案 1 :(得分:14)
Apple的recommendation为extern
:
定义用于通知名称和字典键等用途的字符串的常量。通过使用字符串常量,您可以确保编译器验证指定了正确的值(即,它执行拼写检查)。
不可否认,他们有时会对此不一致。
答案 2 :(得分:3)
#define
定义了一个在编译开始之前被替换的宏,其中extern *** *const
仅修改变量,以便编译器在尝试更改时标记错误。在某些情况下,您会使用#define
,因为您无法使用extern *** *const
。理论上,extern *** *const
将占用内存并需要对内存的引用,但这可能是无关紧要的,因为它可能远离编译器进行优化。
extern *** *const
的编译器和调试比#define
更加友好,当你决定使用哪一个时,这可以作为决定点。
有些人认为像#define
这样的预处理器指令不赞成,这表明你应该使用extern *** *const
而不是#define
但是,虽然预处理器是皱眉状的,但有人说它比变量更安全,因为它在运行时无法更改,而变量可以。
两者都有优点和缺点,我不认为(我自己找不到任何东西)Apple推荐一个优于另一个。我个人的意见是使用预处理器指令#define
而不是extern *** *const
使用它们,这似乎更有益,这就是我所做的。
答案 3 :(得分:1)
如果你有一些全局常量,例如在你的前缀头中导入的Constants.h中,并且你正在为这些常量使用#define宏,那么如果对这些常量进行任何更改,它将重建整个项目常量。在这种情况下,最好分割常量并使用extern作为字符串,整数和其他可以使用extern的东西。
例如,如果您有extern NSString *const kServerURL;
并且您更改了服务器地址,那么它不会重建您的整个项目,但如果您在那里使用define,它将重建它。所以至少对我来说唯一的目的是优化编译时间。