我才刚刚开始,我对此有些挂断。我可能有一个基本的误解,您可以帮助我帮助我。
为什么您可以直接将字符串值分配给NSString*(并且,我敢肯定,许多其他对象类型)?例如,
nsString* s = @"你好,世界!";
我相信,以下代码将分配给S2 S1的 pointer value(因此,仅偶然地向S2提供字符串值)?
nsstring* s1 = @"你好,世界!";
NSString* S2 = S1;
对于许多对象,您是否必须指示一个属性,也就是实例变量,您要分配一个值(即使用setter方法)?该对象本身不应该仅接受指针值的作业吗?或诸如NSString之类的类自动重新解释代码,例如上面的第一个示例,将指示字符串分配给隐含的实例变量,使用隐含的setter?
为什么您可以将字符串值分配给NSSTRING*(并且,我是 当然,许多其他对象类型)直接?
虽然看起来像它,但您并未将字符串的值分配给实例变量。实际上,您将字符串值的地址分配给您的实例变量。现在,真正的问题是当您具有类型的表达时,幕后发生了什么:
NSString * str = @"Hello World";
此表达式代表了 string字面的创建。在C(和Objective-C)严格的超集C)中,字符串文字得到特殊处理。具体来说,以下发生了:
- 当您的代码编译时,将在" Hello World"字符串中创建在数据部分中该程序。
- 当程序执行时,实例变量" str"将分配在堆上。
- " str"实例变量将指向静态字符串" Hello World"的静态内存位置。
您的第一个和第二个示例之间的主要区别在于,在第二个示例中,字符串变量的内存在运行时动态分配在堆上。请注意,在这两种情况下,变量" str"只是动态分配的指针。
后者或多或少。诸如@"Hello World!"
之类的字符串文字被视为Objective-C中的特殊情况:该语法声明的字符串在编译时被静态分配,实例化和缓存以提高性能。从程序员的角度来看,它与调用[NSString stringWithString:@"Hello World!"]
或采用C弦的构造函数没有什么不同 - 您应该将其视为句法糖。
fwiw,Objective-C最近开始扩展@
前缀以允许声明的字典和数组文字,例如:@{ @"key" : @"value" }
或@[ obj1, obj2, obj3 ]
。
这是编译器而不是语言构造的函数。在这种情况下,编译器识别字符串文字并插入一些代码以产生预期的结果。
@"本质上是NSString的 stringwithutf8string方法的速记。
从这里开始:@符号在Objective-C中表示什么?
NSString *s1 = @"Hello, world!";
本质上等同于
NSString *s1 = [NSString stringWithUTF8String:"Hello, world!"];
前者在静态上分配一个新的NSString对象(而不是在运行时在堆上,就像后者一样)。
重要的是要注意,这些只是指针。当您执行NSString *s2 = s1
时,s1
和s2
都请参考同一对象。