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