【问题标题】:This class is not key value coding-compliant for the key openKey. How to fix errors此类与键 openKey 的键值编码不兼容。如何修复错误
【发布时间】:2018-02-09 08:18:51
【问题描述】:

错误的来源。

@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”而终止应用程序,原因:“[<_ttgcs26_swiftdeferrednsdictionaryssss_0x1665dea0> setValue:forUndefinedKey:]:这个类不是键值编码兼容键 openKey。 * 首先抛出调用栈: libc++abi.dylib:以 NSException 类型的未捕获异常终止

有什么问题?

【问题讨论】:

  • 您的 isOpenKey 变量在哪里定义?永远不要使用 value(:forKey)...这是通往地狱的一种方式...
  • isOpenKey是一个什么样的var?看起来像一个布尔。您不能将 Bool 用作字典键。
  • 类 ViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource { @IBOutlet weak var collectionView: UICollectionView! let headerKey: String = "headerKey" let isOpenKey: String = "openKey" 我已经设置好了。
  • 好的。那么 testSection 在崩溃点的值是多少呢?如果它是 nil 那就不好了。
  • 如果取isOpenKey在crash前的值,会正常打印“N”。

标签: swift uicollectionview nsdictionary setvalue


【解决方案1】:

有什么问题?

“问题”是您在 Swift 程序中使用 NSDictionary,而且您到处都在使用键值编码(value(forKey:)setValue(_:forKey:))。停下来。这是 Swift,而不是 Objective-C。使用 Swift 类型和与它们交谈的 Swift 方式。

【讨论】:

    【解决方案2】:

    您使用的NSDictionary 错误。 首先-响应@Willeke的cmets,您不能修改NSDictionary,您需要NSMutableDictionary。你最好使用Dictionary

    那么,你应该打电话给setObject:forKey:,而不是setValue:forKey:

    我必须承认,这个 API 可能有点令人困惑,因为它非常相似:

    您想要将字典键条目映射到对象,这是由setObject:forKey: 完成的,在您的示例中(使用可变字典):testSection.setObject("N", forKey: "openKey")。将 Swift 方式与 Swift Dictionary 一起使用,您将编写 testSection["openKey"] = "N"

    当使用setValue:forKey: 时,您是Key-Value-Coding,例如您正在调用 NSDictionary 实例的方法(“发送消息”),并且消息的名称是您在键值中提供的名称。这将导致类似于调用textSection.openKey = "N",因此例外

    这个类不符合键 openKey 的键值编码

    NSMutableDictionary 的特殊情况下,正如@matt 所提到的,只要您不提供NSString 作为关键参数,setValue:forKeysetObject:forKey 的行为相同 - 在后一种情况下,KVC将被使用。

    【讨论】:

    • 可以将valueForKey:NSDictionarysetValue:forKey:NSMutableDictionary 一起使用。
    • 来自NSDictionary 的文档:“一般来说,键可以是任何对象(只要它符合 NSCopying 协议——见下文),但请注意,在使用键值编码时键必须是字符串”。
    • @Willeke:区分可变字典和非可变字典是对的;尽管如此,setValue:forKey:setObject:forKey 的做法截然相反,我认为这就是原始海报混合的内容。
    • "setValue:forKey: 与 setObject:forKey" setValue:forKey: 调用 setObject:forKey: 截然相反。所以他们几乎不是“截然相反的”;它们更像是同义词。
    • 但我们正在谈论 NSMutableDictionary。
    猜你喜欢
    • 2016-07-15
    • 1970-01-01
    • 2012-08-18
    • 2014-05-17
    • 1970-01-01
    • 2017-09-27
    • 2017-12-15
    • 2011-07-24
    • 1970-01-01
    相关资源
    最近更新 更多