4

我知道如果你在 Mac OS 的源代码中定义了一堆 @"" NSString 对象。这些 NSString 将存储在 Mach-O 库中的一个段中。

Section
sectname __ustring
 segname __TEXT
    addr 0x000b3b54
    size 0x000001b7
  offset 731988
   align 2^1 (2)
  reloff 0
  nreloc 0
   flags 0x00000000
reserved1 0
reserved2 0

0x0000如果我对二进制文件进行十六进制转储,它们将与分隔符一一紧密对齐。我想知道的是Mac OS X中的加载器在程序运行时如何加载这些NSStrings?它们是通过识别分隔符简单地加载0x0000还是这些是二进制文件中其他地方的字符串偏移表,指向单独的 NSString 对象?谢谢。

(我真正想做的是增加其中一个 NSString 的长度,所以我必须知道加载器如何识别这些单独的对象)

补充:我知道如果你在代码中定义像@“abc”这样的CStrings,它将进入cstring段。如果它是像 @"“”" 这样的字符串,并且没有 ascii 字符,根据我的挖掘,它将进入 ustring 部分。

4

2 回答 2

5

有一个包含所有常量 C 字符串的 cstring 部分。每个常量 NSString 只引用这些 C 字符串之一。常量 NSString 的 C 结构体如下所示:

struct NSConstantString {
  Class isa;
  char *bytes;
  int numBytes;
};

__DATA __cfstring部分。

编辑:

__ustring 段与 __cstring 段等效,但 UTF16 字符串除外。所以一个常量 NSString 可以引用 ustring 或 cstring 数据。

对 ustring 数据的唯一引用可能来自它所使用的 cfstring。如果你加长一个字符串,引用下一个字符串的 cfstring 将改为引用加长字符串的尾部,除非你修复它。您可能可以在其他地方找到一些可用空间,您可以将 cfstring 指向。

于 2010-05-22T16:27:11.930 回答
2

不,每个字符串都有一个二进制地址。如果你在一个字符串中插入一个字符,地址将增加它上面的所有字符,你需要调整它们在二进制中引用它们的地址,另外,如果你使段更大,你可能需要根据用于对齐段的填充量来调整任何后续段的位置。重新编译程序并让链接器处理它要容易得多。

NB NSStrings 不会在内部存储为 C 字符序列。这是一个实现细节,但我怀疑 NSStrings 使用 16 位字符宽度。

于 2010-05-22T16:32:24.077 回答