我有一个奇怪的问题,我现在一直在研究/玩几个小时。
我正在开发一个简单的笔记应用程序,将笔记存储在NSMutableDictionary
中,其中Key为标题,Value为笔记。我有一个委托函数,每次更改时都会保存NSTextView
的内容。
-(void)textDidChange:(NSNotification *)notification {
NSString *currentNote = [_mainTextField string];
[Data setNote:currentNote forKey:currentKey];
}
然后将其添加到词典中。
+(void)setNote:(NSString *)note forKey:(NSString *)key {
[allNotes setObject:note forKey:key];
}
虽然currentKey
是一个在其他地方更新的全局变量(我已经过彻底测试并且工作正常)。
这就是奇怪的地方:只要密钥都是唯一的(它们是唯一的),您希望字典为setNote:forKey:
的每次调用更新一个密钥。但相反,它每次都会更新所有以前更新的密钥。所以,如果你有一个像这样的字典。
"John" = "apples";
"David" = "apples";
并且您将“John”更新为“香蕉”
"John" = "bananas";
"David" = "apples";
然后你将“大卫”更新为“橘子”,你会得到这个:
"John" = "oranges";
"David" = "oranges";
我已断断续续并且NSLog出了问题,而我发现的是“John”在setNote:forKey:
方法的开头变为“oranges”,甚至在调用[allNotes setObject:note forKey:key]
行之前。现在,这是我整个程序中唯一一个更改allNotes
字典的地方,但不知何故原始行在函数之前被重新更改甚至叫。第一次进行更改(“香蕉”轮)一切都完美无论字典的大小或哪个条目正在更改,第二次(“橙子”轮)它再次完美地工作,除了也改变了之前改变的行。
我不知道如何在我的代码中更准确地了解原因,因为按下键的确切时刻,textDidChange:
被调用,到那时第一个条目已被更改。值得注意的是,当我停止应用程序并重新运行时,它会回到正常更改第一个应用程序,并再次开始整个应用程序。
另一个奇怪的部分是,Key变量工作正常。我已经检查了调试器:全局变量currentKey
和从它派生的局部变量key
都将是“David”,但这些更改将影响“David”和“John”,其他任何人也在“约翰”之前改变了。它怎么能知道以前编辑过哪些行,只有当前的Key值可以使用?
我当然是可可初学者,但我绝对难过。任何人都可以为我阐明这一点吗?
答案 0 :(得分:1)
当键/值对添加到词典时,键被复制,而值保留。密钥被复制,因此无法更改 - 字典的内部组织基于密钥。
值保留,因为它们必须在字典中继续存在,但如果值是可变类型,则可以对其进行变异。例如。如果您创建了NSTextField
个对象的字典,那么键和NSTextField
对象之间的关联是固定的,但各个文本字段本身的内容可以更改。
在您的代码[_mainTextField string]
中,每次调用时都会返回对相同 NSMutableString
对象的引用。这意味着字典中的每个值都是对同一个可变对象的引用,并为您提供所看到的行为。您可以通过更改[_mainTextField string]
以通过复制内部使用的可变字符串来更改NSString
来解决此问题;或者使用[[_mainTextField string] copy]
复制返回的内容。如果[_mainTextField string]
的目的是返回_mainTextField
当前值的快照(无论其类型是什么 - 样本没有说),前者会更好。