Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 为什么像NSString和NSNumber这样的对象不能被覆盖?_Objective C_Nsstring_Immutability_Mutable - Fatal编程技术网

Objective c 为什么像NSString和NSNumber这样的对象不能被覆盖?

Objective c 为什么像NSString和NSNumber这样的对象不能被覆盖?,objective-c,nsstring,immutability,mutable,Objective C,Nsstring,Immutability,Mutable,关于同一主题有很多帖子,这可能是一个愚蠢的问题,但我一直无法理解这个概念 我知道在将可变字符串分配给不可变字符串时出现的问题,以及为什么我应该使用copy来避免这些问题 我真正不明白的是:什么确切地说NSString不能修改 如果我这样做: NSString *foo = @"Hello World!"; foo = @"Hello everybody!"; 我知道我不是在修改foo的值,而是用新实例替换旧实例。但是,如何定义我不能重写可变对象呢 更新 我尝试运行以下代码: -(void)im

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

我知道在将可变字符串分配给不可变字符串时出现的问题,以及为什么我应该使用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的情况下,它们仍然有不同的地址,即使myMutableString中的任何更改都会反映在myString3中。 在我将myString1分配给myString3之后,myString3所指向的地址不会改变,但是它不再与myMutableString相关,因为我对它所做的每一个更改都将不再反映在myString3中。
是什么导致myString3和myMutableString首先被链接?

当您编写
foo=@“Hello World!”
,foo指向一个
NSString
对象,该对象包含数据
“Hello World!”
,假设该对象位于地址10


当您编写
foo=@“Hello Everyone!”
时,
foo
现在指向一个新对象,该对象的数据为
“Hello Everyone!”
,假设该对象位于地址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处的一个对象,该对象修改了内容“你好,世界!进展如何?”


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

回答得好,我做了一些小的编辑。一般来说,就用法而言,
NSMutableString
并没有真正使用。通常,我们复制字符串或附加它。可变对象主要用于
NSMutableArray
NSMutableDictionary
(还有其他对象,但它们是最常见的两个),因为您可能经常需要动态数组和字典。但如果您使用这些,请记住,如果这些是公共API的一部分,则有时要传递一个
副本。如果你不想让任何人弄乱易变的对象,就让它们不可变。反之亦然,
mutableCopy
。谢谢您的回复。我用我尝试过的一些代码更新了这个问题,但在阅读了你的答案后,它并没有像我预期的那样工作。@Lovato关于可变数据容器,你是对的。如果需要从头开始并通过许多步骤构建字符串,可变字符串可能非常有用。例如,通过检查是否应添加每个参数来添加参数来构建URL。
&myString
获取本地指针的地址,而不是对象的地址。在方法的开始处设置断点,并在调试窗格中查看对象的地址。谢谢!我被测试结果弄糊涂了,但现在一切都清楚了。