我在几篇文章和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";
答案 0 :(得分:17)
使用常量而不是定义的一个实际原因是您可以直接比较(使用==)而不是使用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指针方法在代码大小和执行时间方面要优越得多。
答案 1 :(得分:10)
对于整个应用程序中的给定字符串文字,不一定能保证只有一个NXConstantString对象。很可能不同的编译单元可能对同一个常量字符串有不同的对象。例如,如果有人写了一个插件,那么将为插件中出现的NSString文字生成一个常量字符串,并且将为主机应用程序中的出现生成一个常量字符串,这些将不是指针相等的。
答案 2 :(得分:9)
我听过的最好的论据是const
字符串出现在调试器中,而宏则没有出现。
答案 3 :(得分:0)
static NSString * const SERVER_URL = @"http://subdomain.domain.edu.ar/Folder/";
答案 4 :(得分:-2)
据我所知,#define
只允许您定义C风格的字符串常量。要创建一个常量NSString对象,您必须在标头中声明它,然后在其中一个.m文件中为其赋值。
标题文件:
extern NSString *MyConstantString;
主档案:
NSString *MyConstantString = @"String value";