我有一个奇怪的问题,我已经研究/研究了几个小时了。
我正在开发一个简单的笔记应用程序,将笔记存储在 NSMutableDictionary
中,以 Key 作为标题,以 Value 作为笔记。我有一个委托(delegate)函数,可以在每次更改时保存 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”更新为“bananas”
"John" = "bananas";
"David" = "apples";
然后你将“David”更新为“oranges”,你会得到:
"John" = "oranges";
"David" = "oranges";
我已经断点和 NSLog 了,我发现“John”在 setNote:forKey:
的开头变成了“oranges” > 方法,在调用 [allNotes setObject:note forKey:key]
行之前。 现在,这是我整个程序中唯一更改 allNotes 的地方
字典,但不知何故,在调用函数之前原始行就被重新更改。第一次进行更改(“香蕉”回合)时,无论词典的大小或更改哪个条目,一切都可以完美运行,第二次(“橘子”回合)一切都可以完美运行,除了也更改之前更改的行。
我不知道如何更准确地了解代码中的原因,因为在按下某个键的确切瞬间,textDidChange:
被调用,此时第一个条目已经被改变了。值得注意的是,当我停止应用程序并重新运行时,它会返回到正常更改第一个应用程序,并再次开始整个过程。
另一个奇怪的部分是,关键变量工作正常。我已经检查了调试器:全局变量 currentKey 和从中派生的局部变量 key 都将是“David”,但更改将影响“David” ”和“John”,以及在“John”之前发生的任何其他更改。仅使用当前的 Key 值,它怎么可能知道之前编辑过哪些行?
我诚然是一个 Cocoa 初学者,但我绝对被难住了。谁能帮我解释一下这个问题吗?
最佳答案
当将键/值对添加到字典时,键将被复制,而值将被保留。键被复制,因此无法更改 - 字典的内部组织基于键。
这些值被保留,因为它们在字典中必须继续存在,但如果该值是可变类型,那么它可以被改变。例如。如果您创建 NSTextField
的字典对象,然后是键和 NSTextField
之间的关联对象是固定的,但各个文本字段本身的内容可以更改。
它看起来像你的代码 [_mainTextField string]
返回对相同 NSMutableString
的引用每次调用时都会对象。这意味着字典中的每个值都是对同一个可变对象的引用,并为您提供您所看到的行为。您可以通过更改 [_mainTextField string]
来解决此问题返回NSString
通过复制内部使用的可变字符串;或者通过复制使用 [[_mainTextField string] copy]
返回的内容。如果[_mainTextField string]
的目的是前者更好是返回 _mainTextField
当前值的快照(无论它的类型是什么 - 示例中没有说明)。
关于XCode 在调用函数之前调用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17106876/