objective-c - 编译器是否优化了字符串形成?

标签 objective-c cocoa compiler-construction

我试图回答另一个关于 == 运算符的问题,我创建了这段代码:

NSString *aString = @"Hello";
NSString *bString = aString;
NSString *cString = @"Hello";

if (aString == bString)
    NSLog(@"CHECK 1");

if (bString == cString)
    NSLog(@"CHECK 2");

if ([aString isEqual:bString])
    NSLog(@"CHECK 3");

if ([aString isEqual:cString])
    NSLog(@"CHECK 4");

NSLog(@"%i", aString);
NSLog(@"%i", bString);
NSLog(@"%i", cString);

但对结果感到惊讶:

Equal[6599:10b] CHECK 1
Equal[6599:10b] CHECK 2
Equal[6599:10b] CHECK 3
Equal[6599:10b] CHECK 4
Equal[6599:10b] 8240
Equal[6599:10b] 8240
Equal[6599:10b] 8240

这里有编译器的诡计吗?

最佳答案

显然,字符串唯一性正在发生,至少在单个编译单元内是这样。我建议您简要浏览一下 man gcc,在此期间您将了解“string”的所有用法。您会发现一些与文字 NSString 及其免费桥接对应物 CFString 直接相关的选项:

  • -fconstant-string-class=class-name 设置用于实例化@".. ” 文字。它默认为 NSConstantString 除非您使用的是 GNU 运行时。 (如果你不知道自己是不是,那你就不是。)
  • -fconstant-cfstrings 允许在您编写 CFSTR(...)< 时使用内置函数创建 CFString/

您可以使用 -fwritable-strings 禁用 C 字符串文字的唯一性,尽管不推荐使用此选项。我无法想出一个选项组合来阻止 Objective-C 文件中 NSString 文字的唯一化。 (有人想谈谈 Pascal 字符串文字吗?)

您会看到 -fconstant-cfstringsCFString.hCFSTR() 宏定义中发挥作用,该宏用于创建 CFString 文字:

    #ifdef __CONSTANT_CFSTRINGS__
    #define CFSTR(cStr)  ((CFStringRef) __builtin___CFStringMakeConstantString ("" cStr ""))
    #else
    #define CFSTR(cStr)  __CFStringMakeConstantString("" cStr "")
    #endif

如果您查看 CFString.c 中非内置 __CFStringMakeConstantString() 的实现,您会看到该函数确实使用非常大的 CFMutableDictionary 执行唯一化:

    if ((result = (CFStringRef)CFDictionaryGetValue(constantStringTable, cStr))) {
        __CFSpinUnlock(&_CFSTRLock);
    }
    // . . .
    return result;

另请参阅问题的回复,"What's the difference between a string constant and a string literal?"

关于objective-c - 编译器是否优化了字符串形成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1320161/

相关文章:

ios - 遍历数组,索引错误

macos - 如何获取Finder侧边栏收藏夹内容 cocoa ?

c++ - 编译时断言?

objective-c - 如何从交换的自定义 View 访问方法/变量

c++ - 默认参数值错误 [Visual C++ 2008 中的错误?]

java - 由于边界原因,maven 拒绝编译泛型类,即使在转换类之后也是如此

ios - 选择 UITableView 时使内容可见

iOS 位置管理器在手机锁定约 10 分钟后停止

objective-c - 如何关闭 NSWindow 并从停靠菜单中删除应用程序图标

objective-c - 使用自定义类的 NSMutableArray 作为数据源设置 NSTableView