繁体   English   中英

Objective-C #define指令被妖魔化为String常量

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM