复制字典

时间:2013-11-08 01:47:13

标签: objective-c nsdictionary

我正在尝试用字典测试复制。如果我正确地理解了我的书,当我们制作原始字典的副本时,新字典中的对象将仅引用原始字典中的那些元素(类似于数组的浅表副本)。在下面的示例中,我将字符串对象添加到字典中,然后复制字典并打印两个字典的结果。然后我改变字符串的值并再次打印两个字典。但是,结果与字符串的原始值相同。字典的最后一个印刷品不应该显示字符串的新值吗?

NSMutableString * phoneRef = [NSMutableString stringWithString:@"444"];
NSString * phoneKey = @"phone";
NSDictionary * myDict = [NSDictionary dictionaryWithObjectsAndKeys: phoneRef, phoneKey, nil];

NSMutableDictionary *dictCopy = [myDict mutableCopy];

NSLog(@"%@", myDict);
NSLog(@"%@", dictCopy);

phoneRef = [NSMutableString stringWithString:@"555"];

NSLog(@"%@", myDict);
NSLog(@"%@", dictCopy);

1 个答案:

答案 0 :(得分:2)

我在评论中猜测答案,因为此刻我无法访问Mac,但这就是正在发生的事情。

将字符添加到字典时,字典会保留指向这些对象的指针。

执行此操作时:

phoneRef = [NSMutableString stringWithString:@"555"];
//or even just phoneRef = @"555";

您没有更改phoneRef最初指向的内存位置的内容(您的词典指向的内存位置)。您正在更改phoneRef指针的值,将其指向内存中包含字符串值@"555"的新位置。

但是,字典仍然指向旧的内存位置,该位置仍包含@"444"

但是,使用这种方法:

[phoneRef setString:@"555"];

或者您直接在实例化对象phoneRef(例如replaceOccurrencesOfString:withString:options:range:replaceCharactersInRange:withString:等)上调用的任何其他方法,您实际上是在修改内存地址的内容phoneRef实际指向的是setString:。这些词典在技术上是100%完全未经修改的。它们只包含指向内存地址的指针(它们甚至不知道它们指向的是什么类型的对象,我不认为)。使用NSLog(@"Address of phoneRef: %p", &phoneRef); 方法,更改字典指向的内存地址的值。


为了更清楚地了解正在发生的事情,您可以使用以下内容打印指针的值(所有内容指向的内存地址):

phoneRef = [NSMutableString stringWithString:@"555"];

[phoneRef setString:@"555"];之前和之后以及{{1}}之前和之后抛出该行,以便更清楚地了解正在发生的事情。