NSMutableDictionary 中的更改未反映在父 NSDictionary 中
Posted
技术标签:
【中文标题】NSMutableDictionary 中的更改未反映在父 NSDictionary 中【英文标题】:Changes in NSMutableDictionary not reflecting in parent NSDictionary 【发布时间】:2017-08-02 21:31:22 【问题描述】:问题 1)
我正在使用以下代码从 NSDictionary 创建 NSMutableDictionary:
_allKeysDictionary = [receivedDictionary mutableCopy];
我正在使用以下代码更新 _allKeysDictionary 中的值:
[_allKeysDictionary setObject:[textField text] forKey:@"field"];
但我的父母 NSDictionary
即 receivedDictionary 并未反映 _allKeysDictionary 中所做的更改。
我需要更新receivedDictionary
的值。
问题 2)
我正在使用
(__bridge CFMutableDictionaryRef)
在我的 JSON 响应中保留指向 NSDictionary
之一的指针。但是当我试图重新获得上述CFMutableDictionaryRef
时,我仍然得到NSDictionary
。我不知道出了什么问题。我正在使用以下代码从参考中重新获得字典
NSMutableDictionary *getPointedDict = (__bridge NSMutableDictionary*) dataRefValue;
【问题讨论】:
【参考方案1】:Q1: 但是mutableCopy
方法甚至这么说:创建了一个副本! receivedDictionary
逻辑上不会改变。
更新(完成后):
receivedDictionary = _allKeysDictionary;
或者为了安全起见,以后不能进行任何更改:
receivedDictionary = [NSDictionary dictionaryWithDictionary: _allKeysDictionary];
顺便说一句,你可以写:
_allKeysDictionary[@"field"] = textField.text;
Q2:在 Obj-C(和许多其他语言)中,强制转换不会改变对象的结构。如果是NSDictionary
,它将始终保持为NSDictionary
。所以实际的转换会起作用(即编译器不会告诉你),但是一旦你开始对原始类中没有实现的对象做一些事情,你的应用程序就会崩溃或者你会得到其他未定义的结果。
【讨论】:
【参考方案2】:但我的父母
NSDictionary
即receivedDictionary
并未反映在_allKeysDictionary
中所做的更改
当然不是,您制作了mutableCopy
- 这是一个副本。您现在有两个具有相同键和值的字典。
我需要更新
receivedDictionary
的值
如果是NSDictionary
,你不能这样做,这就是不可变的意思。您可以将receivedDictionary
中存储的引用替换为引用您的新可变字典(或它的不可变副本)的引用,但这并不能满足您希望其他变量存储引用原来的字典。
但是,如果字典中的值本身是可变的,那么您可以更改这些值。例如。如果你 NSDictionary
包含 NSMutableArray
值,那么你可以更改这些数组的元素,但你不能更改哪个数组与字典中的哪个键相关联。
Q2:您不能简单地将对不可变字典的引用转换为可变字典。无论如何,强制转换不会更改引用的对象,它只会更改编译器将其视为的类型(如果该类型与您的程序中断的实际类型不兼容)。
您似乎对对象、引用和可变性不确定;可能是时候做一些研究了。
HTH
【讨论】:
当然。我同意你的最后一点,我会更深入地研究。但只是一个快速的问题。如果我的父字典是可变的,那么其中的所有数组和字典默认都是可变的?? 没有。可变性适用于字典本身,而不是它的值。如果您添加一个可变数组/字典,那么它仍然是可变的,但添加它不会使其可变。 好的.. 明白了。谢谢!【参考方案3】:-
MutableCopy 和复制都在 NSDictionary 上进行深度复制。唯一的区别是 mutableCopy 使您的新 dict 可变。
当您进行深度复制时,您复制的是值,而不是引用,这意味着无论您在新字典上做什么,都不会影响旧值。
另外,您的原始字典是不可变的,即使您复制引用,它的值也不会改变。
【讨论】:
抱歉,副本不深,仅复制存储在字典中的引用。 不。这称为一层深拷贝。字典本身是深度复制的。它的内容是浅拷贝的。 抱歉,不,请参阅 this、this 和 this。 “一层深拷贝”(OLDC)作为一个定义的概念被证明是很难找到的。 This 是 Ruby 中的一种用法,其中clone
(相当于 Obj-C copy
,浅拷贝)不足以完成任务,并且编写了自定义 OLDC - 克隆对象 + 克隆它的引用对象。
但是新字典的内存地址与之前的字典不同,对吧?如果是纯浅拷贝,即使是新字典也应该和前一个字典有相同的地址(指针)。
来自第一个链接“复制对象的一种方法是浅拷贝。在这种情况下,会创建一个新对象 B,并将 A 的字段值复制到 B。”以上是关于NSMutableDictionary 中的更改未反映在父 NSDictionary 中的主要内容,如果未能解决你的问题,请参考以下文章
在从 NSMutableDictionary 加载的 textview 中保存更改的文本
从一个类访问和更改 NSMutableDictionary 的值到另一个 iOS
在 UITableView 中过滤 NSMutableDictionary 数据
如何更改 NSMutableDictionary int 值