1

我才刚刚开始,我对此有点挂断。我可能有一个基本的误解,你可以帮助我。

为什么您可以直接将字符串值分配给 NSString* (而且,我敢肯定,还有许多其他对象类型)?例如,

NSString* s = @"你好,世界!";

而我相信下面的代码会分配给 s2 s1 的指针值(因此只是顺便为 s2 提供了一个字符串值)?

NSString* s1 = @"你好,世界!";

NSString* s2 = s1;

对于许多对象,您是否不必指定要为其分配值的属性(即实例变量)(即,使用 setter 方法)?对象本身不应该只接受指针值的赋值吗?或者诸如 NSString 之类的类是否会自动重新解释代码(例如上面的第一个示例),以使用隐含的 setter 将指示的字符串分配给隐含的实例变量?

4

4 回答 4

3

为什么您可以直接将字符串值分配给 NSString* (而且,我敢肯定,还有许多其他对象类型)?

虽然它可能看起来像,但您并没有将字符串的值“直接”分配给实例变量。您实际上是将字符串值的地址分配给您的实例变量。现在,真正的问题是当你有一个类型的表达式时,幕后发生了什么:

NSString * str = @"Hello World";

此表达式表示字符串文字的创建。在 C(以及作为 C 的严格超集的 Objective-C)中,字符串文字得到特殊处理。具体来说,会发生以下情况:

  1. 编译代码后,将在程序的数据部分中创建字符串“Hello World”。
  2. 当程序执行时,将在堆上分配一个实例变量“str”。
  3. “str”实例变量将指向存储实际字符串“Hello World”的静态内存位置。

第一个和第二个示例之间的主要区别在于,在第二个示例中,字符串变量的内存是在运行时在堆上动态分配的。请注意,在这两种情况下,变量“str”只是一个动态分配的指针。

于 2012-11-09T01:37:49.200 回答
1

或多或少是后者。类似的字符串文字@"Hello World!"在 Objective-C 中被视为一种特殊情况:使用该语法声明的字符串在编译时被静态分配、实例化和缓存以提高性能。[NSString stringWithString:@"Hello World!"]从程序员的角度来看,它与调用或使用 C 字符串的构造函数没有什么不同——您应该将其视为语法糖。

FWIW,Objective-C 最近开始扩展@前缀以允许声明字典和数组字面量,例如:@{ @"key" : @"value" }@[ obj1, obj2, obj3 ].

于 2012-11-09T01:32:17.477 回答
0

这是编译器的功能,而不是语言结构。在这种情况下,编译器会识别字符串文字并插入一些代码以产生预期的结果。

@"" 本质上是 NSString 的 +stringWithUTF8String 方法的简写。

从这里获取: @符号在objective-c中代表什么?

于 2012-11-09T01:31:54.143 回答
0
NSString *s1 = @"Hello, world!";

本质上等同于

NSString *s1 = [NSString stringWithUTF8String:"Hello, world!"];

前者静态分配一个新的 NSString 对象(而不是像后者那样在运行时在堆上)。

重要的是要注意这些只是指针。当你这样做时NSString *s2 = s1,两者都s1引用s2同一个对象。

于 2012-11-09T01:33:10.367 回答