错误的来源。
@objc func selectHeader(sender: UIButton) -> Void {
var testSection = NSDictionary()
var openValue = String()
testSection = self.arrHeader.object(at: sender.tag) as! NSDictionary
openValue = testSection.value(forKey: self.isOpenKey) as! String
// value change
if openValue == "Y" {
testSection.setValue("N", forKey: self.isOpenKey) <—— App crash self.isOpenKey == “openKey”
} else {
testSection.setValue("Y", forKey: self.isOpenKey) <—— App crash self.isOpenKey == “openKey”
}
let section: NSIndexSet = NSIndexSet(index: (sender.tag))
self.collectionView.reloadSections(section as IndexSet)
}
TestSection.setValue因以下错误而崩溃。
2018-02-09 16:43:38.141 [10730:2091077] *由于未捕获的异常'NSUnknownKeyException'而终止应用程序,原因:'[&lt; _TtGCs26_SwiftDeferredNSDictionarySSSS_ 0x1665dea0&gt; setValue:forUndefinedKey:]:此类与密钥openKey不符合密钥值编码。 * 第一次抛出调用堆栈: libc ++ abi.dylib:以NSException类型的未捕获异常终止
有什么问题?
答案 0 :(得分:1)
有什么问题?
“问题”是你在Swift程序中使用NSDictionary,而且你在整个地方使用键值编码(value(forKey:)
,setValue(_:forKey:)
)。停下来。这是Swift,而不是Objective-C。使用Swift类型和Swift与他们交谈的方式。
答案 1 :(得分:-2)
您使用的是NSDictionary
错误。
首先 - 在回复@Willeke的评论时,您无法修改NSDictionary
,需要NSMutableDictionary
。您甚至可能希望使用Dictionary
。
然后,您应该致电setObject:forKey:
,而不是setValue:forKey:
我必须承认这个API可能有点令人困惑,因为它看起来很相似:
你想要的是映射一个对象的Dictionary键入口,由setObject:forKey:
完成,在你的例子中(带有一个可变字典):testSection.setObject("N", forKey: "openKey")
。使用Swift方法和Swift Dictionary
,您可以编写testSection["openKey"] = "N"
使用setValue:forKey:
时,您键值编码,例如您正在调用方法(“发送消息”)到NSDictionary
实例,并且消息的名称是您在键值中提供的。这会导致调用textSection.openKey = "N"
,因此执行
此类与密钥openKey
不符合密钥值编码
在NSMutableDictionary
的特殊情况下,如@matt所述,setValue:forKey
和setObject:forKey
的行为相同,只要您不提供NSString
作为关键字参数 - 在后一种情况下,将使用KVC。