静态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 *位? 还是我错过了什么?

将文字转化为常量是一个很好的做法,因为:

  1. 它有助于避免错别字,就像你说的
  2. 如果你想改变常数,你只需要在一个地方改变它

我更喜欢使用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将所有引用指向内存中的一个地方。 这是更高效的内存和性能,这在移动设备上非常重要。