我在几篇文章和 Apple 的代码指南中读到,在 Objective-C 中,字符串常量应定义为 extern NSString *const MY_CONSTANT;
并且应避免使用 #define 指令。这是为什么?我知道 #define
是在预编译时运行的,但所有字符串都将共享相同的内存地址。我读到的唯一优点是,如果必须更新或更改常量,则不必重新编译整个项目。所以这就是应该避免#define 的原因吗?
谢谢
更新:在这种情况下,使用#define 是好还是有更好的方法?
/* Constants Definition */
#define SERVER_URL @"http://subdomain.domain.edu.ar/Folder/"
NSString *const ServerURL = SERVER_URL;
NSString *const LoginURL = SERVER_URL@"welcome.asp";
NSString *const CommandURL = SERVER_URL@"com.asp";
最佳答案
使用常量而不是定义的一个实际原因是您可以进行直接比较(使用 ==)而不是使用 isEqual:
。考虑:
NSString * const kSomeStringConstant = @"LongStringConstantIsLong";
...
[someArray addObject:kSomeStringConstant];
if ([someArray lastObject] == kSomeStringConstant)
{
...
}
这是可行的,因为 ==
比较会将相同的 const 指针与单个 NSString
对象进行比较。但是,使用 #define
:
#define STRING_CONSTANT @"MacrosCanBeEvil";
...
[SomeArray addObject:STRING_CONSTANT]; // a new const `NSString` is created
if ([someArray lastObject] == STRING_CONSTANT) // and another one, here.
{
...
}
这不会成功,因为这两个字符串会有唯一的指针。要有效地比较它们,您必须使用 isEqual:
if ([[someArray lastObject] isEqual:STRING_CONSTANT])
{
...
}
就执行时间而言,这比简单的 ==
比较要昂贵得多。
另一个动机可能是可执行文件本身的大小。 #defined 常量实际上会出现在代码中使用它的任何位置。这可能意味着该字符串在您的可执行文件中多次出现。相反,常量应该(对于现代编译器)只定义一次,所有进一步的使用都将引用指向该定义的指针。
现在,在有人因为过早的优化而对我大喊大叫之前,请考虑这两种方法在实现方面几乎相同,但 const 指针方法在代码大小和执行时间方面要优越得多。
关于为字符串常量妖魔化的 Objective-C#define 指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1977489/