静态NSString用法与内联NSString常量

sic*_*ckp 42 objective-c nsstring ios

在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];
Run Code Online (Sandbox Code Playgroud)

而不仅仅是:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellId"];
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:style reuseIdentifier:@"CellId"];
Run Code Online (Sandbox Code Playgroud)

我假设它是为了保护我不会在编译器无法捕获的标识符名称中输入错误.但如果是这样,我不能只是:

#define kCellId @"CellId"
Run Code Online (Sandbox Code Playgroud)

并避免静态NSString*位?或者我错过了什么?

Tom*_*ing 59

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

  1. 它有助于避免拼写错误,就像你说的那样
  2. 如果要更改常量,只需在一个位置更改它

我更喜欢使用,因为它比它更安全.我倾向于避免预处理器,除非我真的需要它.static const NSString* static NSString* const#define

  • 并且可以在gdb中轻松检查字符串常量.#define是一个真正的痛苦.但是你在这里使用const是不正确的.它需要是"静态NSString*const".你的const排序实际上并没有在objc中实现任何有用的东西.尝试以这种方式重新分配你的字符串变量与你的方式,你会发现在一种情况下你得到编译器错误而另一种情况你没有. (18认同)
  • @uchuugaka也许通过"避免预处理器",他的意思是"避免依赖预处理器宏替换(即`#define`)和所有可能带来的潜在问题". (3认同)

Ale*_*ray 36

我喜欢这里的所有答案,而没有一个如何正确宣布其中的简单例子......所以......

如果你想让常量在外部可见(即"全局")....在标题中声明它...

extern NSString *const MyTypoProneString;

并在定义它.m的文件,OUTSIDE任何@implementation像...

NSString * const MyTypoProneString = @"iDoNtKnOwHoW2tYpE";

这就是说......如果你只是想要一个static const是本地的,以你的类的实现(甚至一定的方法!)......简单地声明字符串INSIDE的实现(或方法)的...

static NSString *MavisBeacon = @"She's a freakin' idiot";

编辑 虽然我确实展示了如何做到这一点 ......我还没有确信这种风格在任何方面都比更简洁,更简单,更少重复的单一声明更好,á...

#define SomeStupidString @"DefiningConstantsTwiceIsForIdiots"
Run Code Online (Sandbox Code Playgroud)

使用#define它们......它们不那么烦人了......只是不要让预处理器 - 玩家 - 仇敌让你失望.

  • 稍微过时,但实际上有一个非常,非常好的理由不使用#define - #define宏基本上是替换 - 所以无论何时在代码中调用SomeStupidString,预处理器都会用*new*string文字替换它.使用extern/static const将所有引用指向内存中的单个位置.这**内存效率更高,性能更高. (6认同)
  • Matt S.的评论其实不正确.在应用程序中的任何位置,相同的字符串文字指向同一个对象.创建两个NSString文字并检查它们的指针.看来,即使在RELEASE中,它们也是同一个对象. (3认同)

out*_*tis 9

你应该制作静态变量const.

静态变量和宏之间的一个区别是宏与调试器不能很好地兼容.宏也不是类型安全的.

很多针对CC++的static-var-vs-macro建议都适用于Obj-C.