字符串常量和字符串文字之间有什么区别?
我正在学习Objective-C和Cocoa,并且遇到了以下说法:
The Cocoa frameworks expect that global string constants rather than string literals are used for dictionary keys, notification and exception names, and some method parameters that take strings.
我只使用过高级语言,因此不必过多考虑字符串的细节。字符串常量和字符串文字有什么区别?
解决方案
回答
让我们使用C ++,因为我的Objective C完全不存在。
如果将字符串存储到常量变量中:
const std::string mystring = "my string";
现在,当我们调用方法时,使用的是my_string,而我们使用的是字符串常量:
someMethod(mystring);
或者,我们可以直接使用字符串文字调用这些方法:
someMethod("my string");
可能是因为它们鼓励我们使用字符串常量,原因是因为Objective C不会进行" interning";也就是说,当我们在多个地方使用相同的字符串文字时,实际上是指向该字符串的单独副本的不同指针。
对于字典键,这有很大的不同,因为如果我可以看到两个指针都指向同一个东西,那比进行整个字符串比较以确保字符串具有相等的值要便宜得多。
编辑:Mike,在Cstrings中是不可变的,并且具有相同值的文字字符串都以相同的字符串值结尾。我想对于字符串不可变的其他语言也是如此。在具有可变字符串的Ruby中,它们提供了一种新的数据类型:符号(" foo"与.foo,其中前者是可变字符串,而后者是常用于哈希键的不可变标识符)。
回答
在Objective-C中,语法" @" foo""是" NSString"的不变的文字实例。它不会像Mike假设的那样从字符串文字中生成常量字符串。
Objective-C编译器通常在编译单元中执行内部文字字符串,也就是说,它们合并了同一文字字符串的多种用法,并且链接程序有可能在直接链接到单个二进制文件的编译单元中进行额外的实习。 (由于Cocoa区分可变字符串和不可变字符串,并且文字字符串也始终是不可变的,所以这可以直接且安全。)
另一方面,常量字符串通常使用如下语法声明和定义:
// MyExample.h - declaration, other code references this extern NSString * const MyExampleNotification; // MyExample.m - definition, compiled for other code to reference NSString * const MyExampleNotification = @"MyExampleNotification";
此处的语法练习的重点是,通过确保即使在同一地址空间中的多个框架(共享库)中也仅使用该字符串的一个实例,可以有效地使用该字符串。 (关键字const的位置很重要;它保证指针本身保证是恒定的。)
尽管在25MHz 68030工作站和8MB RAM的情况下,燃烧内存并不像以前那么大,但是比较字符串是否相等可能需要一些时间。确保大多数时间上相等的字符串也将成为指针相等的帮助。
举例来说,我们要按名称订阅对象的通知。如果我们使用非常量字符串作为名称,则在发布NSNotificationCenter通知时,在确定谁对此字符串感兴趣时,可能会进行大量的逐字节字符串比较。如果由于被比较的字符串具有相同的指针而使大多数比较短路,那么这将是一个巨大的胜利。