静态NSString使用与内联NSString常量
在Objective-C中,我的理解是指令@“foo”定义了一个常量NSString。 如果我在多个地方使用@“foo”,则引用同一个不可变的NSString对象。
为什么我经常看到这个代码片段(例如在UITableViewCell中重用):
static NSString *CellId = @"CellId"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellId]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:style reuseIdentifier:CellId]; 而不仅仅是:
 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellId"]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:style reuseIdentifier:@"CellId"]; 
我认为这是为了防止编码器在标识符名称中出现拼写错误。 但如果是这样,我不能:
 #define kCellId @"CellId" 
并避免静态NSString *位? 还是我错过了什么?
将文字转化为常量是一个很好的做法,因为:
- 它有助于避免错别字,就像你说的
- 如果你想改变常数,你只需要在一个地方改变它
 我更喜欢使用static const NSString*static NSString* const因为它比#define更安全。 我倾向于避免预处理器,除非我真的需要它。 
我爱这里所有的答案没有一个简单的例子,如何正确地申报一个…所以…
如果你想要常量在外部可见(即“全局”)….在头文件中声明…
 extern NSString *const MyTypoProneString; 
 并在.m文件中定义它,在任何@implementation如… 
 NSString * const MyTypoProneString = @"iDoNtKnOwHoW2tYpE"; 
 这就是说…如果你只是想要一个static const 是本地的你的类的实现( 甚至某种方法! )…只需声明stringINSIDE实现(或方法)为… 
 static NSString *MavisBeacon = @"She's a freakin' idiot"; 
编辑虽然我显示如何做到这一点 …我还没有相信,这种风格是在任何方面比可笑的更短,更简单,重复性更低的单声明,á拉..
 #define SomeStupidString @"DefiningConstantsTwiceIsForIdiots" 
 使用#define的…他们是less烦人..只是不要让预处理器玩家仇恨让你失望。 
 你应该使静态variables为const 。 
静态variables和macros之间的一个区别是macrosdebugging器不能很好地运行。 macros也不是types安全的。
C和C ++的大部分static-var-vs-macrobuild议都适用于Obj-C。
 不能保证在多个地方使用@"foo"时,运行时会为它们使用相同的存储空间,编译单元或库边界当然不一定是这种情况。 
 我宁愿使用static NSString *string = @"foo" ,特别是与大量的文字string。 
我认为这是为了防止编码器在标识符名称中出现拼写错误。
正确。 这只是基本的防守编程练习。 编译结果(希望)是相同的任何方式。
但如果是这样,我不能:
#define kCellId @"CellId"并避免静态NSString *位? 还是我错过了什么?
 是。 但是,至less在编译单元中, kCellId符号将被全局定义。 声明一个静态variables使符号在该块的本地。 
您通常会将string常量定义为全局variables或静态variables,而不是预处理器定义。 这有助于确保您只处理不同编译单元之间的单个string实例。
所以,我迟到了一点,但在SO的C / C ++领域,这个问题已经被多次以各种方式提出来了,但基本上这里是我对alex grey的一个扩展版:
任何时候你认为你应该使用#define作为stringmacros,你大概可能不应该这样做。 原因是因为#definemacros基本上是对预处理器的正则expression式replace。 只要预处理器看到一个被调用的macros,它就会用你定义的任何东西来replace它。 这意味着每一次新的string文字将被分配到内存中,这在像单元重用标识符(这是为什么苹果的UITableViewController默认代码使用静态)这样的地方是非常糟糕的。
正如Eonil提到的,使用extern / static const将所有引用指向内存中的一个地方。 这是更高效的内存和性能,这在移动设备上非常重要。