Objective c 参考与使用Obj-C NSString复制

Objective c 参考与使用Obj-C NSString复制,objective-c,memory,reference,Objective C,Memory,Reference,我确实找到了一些关于这个话题的讨论,但这超出了我目前的理解水平。我正在阅读Kochan的“Objective-C,4e中的编程”,我在关于NSString对象的部分。首先,我在玩的代码,这样我可以问我的问题: NSString *strA = @"StringA"; NSString *strB = @"StringB"; NSLog(@"Value of strA: %@",strA); NSLog(@"Value of strB: %@",strB); strB = strA; // st

我确实找到了一些关于这个话题的讨论,但这超出了我目前的理解水平。我正在阅读Kochan的“Objective-C,4e中的编程”,我在关于NSString对象的部分。首先,我在玩的代码,这样我可以问我的问题:

NSString *strA = @"StringA";
NSString *strB = @"StringB";
NSLog(@"Value of strA: %@",strA);
NSLog(@"Value of strB: %@",strB);

strB = strA; // strB should point to strA's memory location
NSLog(@"New value of strB: %@",strB); //correctly logs as "StringA"
strA = @"StringA has been changed.";
NSLog(@"New value of strB: %@",strB); //logs as "StringA" still
NSLog(@"New value of strA: %@",strA); //correctly logs as "StringA has been changed"
我的理解是,说strB=strA意味着strB指向strA的内存位置,所以对strA的任何更改也将转到strB。然而,这并没有发生。Kochan说这是应该的,为了避开它,建议使用

strB = [NSString stringWithString: strA];
据我所见,这两种方法都有效。我可以说strB=strA,然后更改strA,但是strB仍然保留它收到的值(更改之前的strA值)

我认为这可能是因为NSString是不可变的,但如果是这样,为什么我可以在初始化后更改str1和str2的值呢?我错过了什么?谢谢

我的理解是,说strB=strA意味着strB指向strA的内存位置,所以对strA的任何更改也将转到strB

对strA内存位置的更改--是。更改为指向同一位置的完全不相关的指针,该位置现在指向其他位置——否

我的理解是,说strB=strA意味着strB指向strA的内存位置,所以对strA的任何更改也将转到strB

对strA内存位置的更改--是。更改为指向同一位置的完全不相关的指针,该位置现在指向其他位置——否

我的理解是说strB=strA意味着strB是 指向strA的内存位置,因此对strA的任何更改都将 去strB

是的,不过可以更清楚地说,
strB
strA
都指向同一个对象

我可以说strB=strA,然后更改strA,但strB仍然保留 接收到的值(仅更改之前的strA值)

如果更改
strA
,则必须使
strA
指向不同的字符串。NSString是不可变的,所以您不能更改它们——只能替换它们。所以,如果你说:

strA = [strA stringByAppendingString:@"foo"];
然后
strA
不再指向原始字符串<当然,code>strB仍然指向原始对象,并且该对象保持不变,因此
strA
指向的字符串和
strB
指向的字符串是不同的对象

我错过了什么

我认为您认为新对象是在执行赋值时创建的
strB=strA,但实际上两个指针都将指向该语句后面的同一个对象。当您“更改”
strA
时,将创建一个新对象

现在,如果你谈论的是可变字符串,事情会有所不同,你当然可以改变它。然后你会遇到这样的情况:

NSMutableString *mstrA = [@"foo" mutableCopy];
NSMutableString *mstrB = mstrA;     // now mstrB points to the same object as mstrA
[mstrA appendString:@"bar"];
NSLog(@"%@", mstrB);                // will log @"foobar" because the string actually changed
我的理解是说strB=strA意味着strB是 指向strA的内存位置,因此对strA的任何更改都将 去strB

是的,不过可以更清楚地说,
strB
strA
都指向同一个对象

我可以说strB=strA,然后更改strA,但strB仍然保留 接收到的值(仅更改之前的strA值)

如果更改
strA
,则必须使
strA
指向不同的字符串。NSString是不可变的,所以您不能更改它们——只能替换它们。所以,如果你说:

strA = [strA stringByAppendingString:@"foo"];
然后
strA
不再指向原始字符串<当然,code>strB
仍然指向原始对象,并且该对象保持不变,因此
strA
指向的字符串和
strB
指向的字符串是不同的对象

我错过了什么

我认为您认为新对象是在执行赋值时创建的
strB=strA,但实际上两个指针都将指向该语句后面的同一个对象。当您“更改”
strA
时,将创建一个新对象

现在,如果你谈论的是可变字符串,事情会有所不同,你当然可以改变它。然后你会遇到这样的情况:

NSMutableString *mstrA = [@"foo" mutableCopy];
NSMutableString *mstrB = mstrA;     // now mstrB points to the same object as mstrA
[mstrA appendString:@"bar"];
NSLog(@"%@", mstrB);                // will log @"foobar" because the string actually changed

有两种方式来思考这里发生的事情。一个稍微低级一点的问题是,您正在处理一个称为指针的构造。指针保存内存地址的方式与
int
变量保存整数值的方式完全相同。如果将一个
int
分配给另一个
int
,则更改第一个,第二个不变:

int i1 = 10;
int i2 = i1;
i1 = 600;    // i2 still 10
指针也是如此


另一种(可能更有效)的思考方式是
strA
strB
实际上是对象的名称。如果通过一个名称将一个对象指定给另一个名称,则两个名称都包含相同的对象。撇开内存管理和对象生存期的问题不谈,您可以将一个名称重新分配给另一个对象,另一个名称将继续指向原始对象。

有两种方法来考虑这里发生的事情。一个稍微低级一点的问题是,您正在处理一个称为指针的构造。指针保存内存地址的方式与
int
变量保存整数值的方式完全相同。如果将一个
int
分配给另一个
int
,则更改第一个,第二个不变:

int i1 = 10;
int i2 = i1;
i1 = 600;    // i2 still 10
指针也是如此

另一种(可能更有效)的思考方式是
strA
strB
实际上是对象的名称。如果通过一个名称将一个对象指定给另一个名称,则两个名称都包含相同的对象。撇开内存管理和对象生存期问题不谈,您可以将一个名称重新分配给另一个对象,另一个名称将继续指向原始对象<