Mach-O加载器如何加载不同的NSString对象?

时间:2010-05-22 15:58:12

标签: objective-c macos loader mach-o

我知道如果你在Mac OS的源代码中定义了一堆@“”NSString对象。这些NSStrings将存储在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部分。

2 个答案:

答案 0 :(得分: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的空闲空间。

答案 1 :(得分:2)

没有。每个字符串都有二进制的地址。如果你在一个字符串中插入一个字符,那么地址将增加其上面的所有字符,你需要在二进制文件中的任何地方调整它们的地址,如果你使段更大,你可能需要调整任何后续段的位置取决于段的对齐有多少包装。重新编译程序并让链接器处理它会容易得多。

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