![](/img/trans.png)
[英]What is the best way to define string constants in an objective-c protocol?
[英]Objective-C #define directive demonized for String constants
我在几篇文章和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:
进行逐个字符的比较isEqual:
if ([[someArray lastObject] isEqual:STRING_CONSTANT])
{
...
}
就执行时间而言,这比简单的==
比较要昂贵得多。
另一个动机可能是可执行文件本身的大小。 #defined常量实际上会出现在代码中使用的任何位置。 这可能意味着字符串在您的可执行文件中出现多次。 相反,常量应该(使用现代编译器)只定义一次,并且所有进一步的使用都将引用指向该定义的指针。
现在,在有人对我进行过早优化之前,请考虑两种方法在实现方面几乎完全相同,但const指针方法在代码大小和执行时间方面要优越得多。
对于整个应用程序中的给定字符串文字,不一定能保证只有一个NXConstantString对象。 很可能不同的编译单元可能对同一个常量字符串有不同的对象。 例如,如果某人编写插件,将为插件中的NSString文字的出现生成一个常量字符串,并且将为主机应用程序中的出现生成一个常量字符串,这些将不是指针相等的。
我听过的最好的论点是const
字符串出现在调试器中,而宏则没有出现。
static NSString * const SERVER_URL = @"http://subdomain.domain.edu.ar/Folder/";
据我所知, #define
只允许你定义C风格的字符串常量。 要创建常量NSString对象,必须在标头中声明它,然后在其中一个.m文件中为其指定值。
头文件:
extern NSString *MyConstantString;
主文件:
NSString *MyConstantString = @"String value";
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.