Objective-C: #define与extern const的区别

13

我知道这个问题以前已经被问过了,但我似乎在苹果的文档中找不到相关信息;也许你们中有些人知道。

很多Objective-C代码都有一个跨文件常量,使用#define在一个.h文件中定义。其他人则使用一种.m包含常量并在.h文件中使用extern引用的方法。

我理解它们之间的区别,包括优缺点,但是苹果公司有没有说明在iOS开发中应该使用哪种方法呢?


3
我认为关于这个问题没有真正的通用建议。即使是苹果的代码也往往在这方面不一致。 - user529758
这也是我注意到的。我认为可能是一些“旧”的做法与较新的做法之间的区别。 - DCMaxxx
即使在代码审查中, 对它们都没问题。 - Anoop Vaidya
4个回答

23

使用 #define 而非 extern 的问题在于编译器无法进行类型检查。如果你用 #define 定义一个字符串,那么在需要使用数字的地方也可能会不小心使用该字符串。如果使用静态 NSString,编译器将在你试图在其它不应该是字符串的地方使用时发出警告。


1
不应该。尽管答案是正确的,但问题明确表示“我了解差异,包括优缺点,但苹果是否指出在iOS开发中使用哪个?” - DCMaxxx

14

苹果公司的建议是使用extern

为用作通知名称和字典键等目的而使用的字符串定义常量。通过使用字符串常量,您可以确保编译器验证指定了正确的值(即它执行拼写检查)。

不过有时候他们在这方面并不一致。


4
一个#define定义了一个宏,它在编译开始之前被替换,而extern *** *const仅仅修改变量,以便编译器会在你试图改变它时标记一个错误。有些情况下,你需要使用#define,因为你不能使用extern *** *const。理论上,extern *** *const将占用内存并需要对内存的引用,但这是微不足道的,因为它可能会从编译器中优化掉。 extern *** *const#define更加友好于编译器和调试,这可能是你选择使用哪个的决定因素。
一些人认为像#define这样的预处理指令是不受欢迎的,这表明你应该使用extern *** *const而不是#define
但是虽然预处理器备受批评,但有些人认为它比变量更安全,因为它不能在运行时更改,而变量可以。
两者都有其优点和缺点,我认为(我自己找不到任何东西)苹果没有推荐其中之一。我的个人意见是在看起来更有利的情况下,混合使用预处理指令#defineextern *** *const,这就是我所做的。

1
如果您有一些全局常量,例如在Constants.h中,并在前缀头文件中导入,您使用#define宏来定义这些常量,如果对这些常量进行任何更改,将重新构建整个项目。在这种情况下,最好拆分您的常量,并对可以使用extern的字符串,整数和其他所有内容使用extern。
例如,如果您有extern NSString *const kServerURL;并更改服务器地址,则不会重新构建整个项目,但如果在那里使用define,则会重新构建。因此,至少对我来说,唯一的目的是优化编译时间。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接