2013-06-24 14 views
1

关于同一主题有很多帖子,这可能是一个愚蠢的问题,但我一直无法理解这个概念。为什么像NSString和NSNumber这样的对象不能被覆盖?

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

我不明白的是:究竟是什么意思,一个NSString不能被修改?

如果我这样做:

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

我明白我没有修改Foo的值,而是用一个新的,而替换旧的实例。但是,那么如何定义我不能重写一个可变对象呢?

UPDATE 我试图运行下面的代码:

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

+0

'&myString'获取本地指针的地址,而不是对象的地址。在方法的开始处设置断点,并在调试窗格中观察对象的地址。 –

+0

谢谢!我对测试结果感到困惑,但现在一切都很清楚。 –

回答

2

当你写foo = @"Hello World!";,富指着拥有数据"Hello World!"NSString对象,让我们说,这个对象所在地址为10

当你写foo = @"Hello everybody!"foo现在指向具有新对象数据"Hello everybody!",让我们说这个对象驻留在地址50.第一个对象根本没有被修改,你只是让foo指向另一个地址的另一个对象。

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

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. 

现在foo的指向对象的地址10,已修改的内容"Hello World!How is it going?"

在第一种情况下,您无法修改NSString,因为它没有提供任何方法来更改该地址处的数据。这是不变的。另一方面NSMutableString通过appendString:appendString:等方法为您提供该功能。这样,您可以在同一地址更改对象的内容,而无需创建新对象来进行这些更改。

+0

很好的回答,我做了一些小的修改。作为一般性评论,在使用方面,“NSMutableString”并没有真正使用。一般来说,我们制作一个字符串的副本或附加它。可变对象主要用于'NSMutableArray'和'NSMutableDictionary'(还有其他的,但这些是最常见的),因为你可能经常需要动态数组和字典。但是,如果你使用这些,记得有时候传递一个'copy',如果这些是你的公共API的一部分的话。如果你不想让任何人搞乱可变对象,使它们不可变。或者'mutableCopy'反过来。 – swiftcode

+0

谢谢你的回复。我用我试过的一些代码更新了这个问题,但它没有正常工作,因为我在阅读你的答案后期待着。 –

+0

@DiegoArmandoRincon查看我的评论。 –

相关问题