为什么NSString和NSNumber等对象无法覆盖?

时间:2013-06-24 10:52:18

标签: objective-c nsstring immutability mutable

有很多关于同一主题的帖子,这可能是一个愚蠢的问题,但我无法理解这个概念。

我知道将可变字符串分配给不可变字符串时出现的问题,以及为什么我应该使用copy来避免这些问题。

我真正理解的是:无法修改NSString的确切含义是什么?

如果我这样做:

NSString *foo = @"Hello World!";
foo = @"Hello everybody!";

我知道我不是在修改foo的值,而是用新的实例替换旧的实例。但是,如何定义我不能重写一个可变对象呢?

更新 我尝试运行以下代码:

-(void)immutable
{
    NSString *myString1 = @"Hello!";
    NSString *myString2 = myString1;

    NSLog(@"myString1 address: %p", &myString1); //Prints 0xbfffdb30
    NSLog(@"myString2 address: %p", &myString2); //Prints 0xbfffdb2c

    myString2 = @"Good bye!";
    NSLog(@"myString2 address: %p", &myString2); //Prints 0xbfffdb2c

    NSMutableString *myMutableString = [NSMutableString stringWithString:@"Hello"];
    NSString *myString3 = myMutableString;

    NSLog(@"myMutableString address: %p", &myMutableString); //Prints 0xbfffdb28
    NSLog(@"myString3 address: %p", &myString3); //Prints 0xbfffdb24

    [myMutableString setString:@"Hello World"];
    NSLog(@"myString3: %@", myString3); //Prints Hello World

    myString3 = myString1;
    NSLog(@"myString3 address: %p", &myString3); //Prints 0xbfffdb24

    [myMutableString setString:@"Nothing to do"];
    NSLog(@"myString3: %@", myString3); //Prints Hello!
}

myString1和myString2的地址不同,我并不感到惊讶,因为两者都是不可变对象。但即使在为myString2指定了不同的字符串之后,它仍然指向与以前相同的地址。它不应该改变吗?

但是在myMutableString和myString3的情况下,即使myMtring3中的任何更改都会反映在myString3中,它们仍然具有不同的地址。 在将myString1分配给myString3之后,myString3指向的地址不会改变,但是它不再与myMutableString相关,因为我对它所做的每个更改都不会再反映在myString3中。 是什么导致myString3和myMutableString首先被链接?

1 个答案:

答案 0 :(得分:2)

当您编写foo = @"Hello World!";时,foo指向具有数据NSString的{​​{1}}对象,假设此对象位于地址10处。

当您编写"Hello World!"时,foo = @"Hello everybody!"现在指向一个具有数据foo的新对象,假设此对象位于地址50.第一个对象未​​被修改你只是让foo指向另一个地址的另一个对象。

如果这些字符串是可变的,您可以修改内容,

"Hello everybody!"

foo现在指向地址为10的对象,该对象修改了内容NSMutableString *foo = @"Hello World!".mutableCopy; //LEt's say, it's @ adress 10 [foo appendString:@"How is it going?"]; // IT's still @ adress 10, but with new content.

在第一种情况下,您无法修改"Hello World!How is it going?",因为它没有为您提供任何方法来更改该地址的数据。这是不变的。另一方面,NSString通过NSMutableStringappendString:等方法为您提供这种能力。这样,您可以在同一地址更改对象的内容,而无需创建新对象来进行更改。