swift - 取消归档 Swift 词典时的 EXC_BAD_INSTRUCTION

标签 swift nsdictionary nscoding nskeyedarchiver

我正在尝试取消存档实现 NSCoding 协议(protocol)的自定义对象。此类称为 Reservation,其属性之一是 Swift 字典:

class Reservation {
  //...
  var orderedExtras : [CarExtra : Int]?
}

CarExtra 还实现了 NSCoding。 现在,当我尝试使用

将文件写入磁盘时
NSKeyedArchiver.archiveRootObject(reservations, toFile: ArchiveURL.path!)

一切都很好。但是,我从磁盘读取该对象时遇到问题。 当我尝试使用

取消归档对象时
 required convenience init?(coder aDecoder: NSCoder) {
      let extras = aDecoder.decodeObjectForKey("orderedExtras") as? [CarExtra : Int]
 }

它给了我一个

EXC_BAD_INSTRUCTION(code=EXC_I386_INVOP, subcode = 0x0)

异常。如果我尝试将未归档的对象视为 NSDictionary

let extras = aDecoder.decodeObjectForKey("orderedExtras") as? NSDictionary

它不会崩溃,我可以提取我保存的数据。 有人可以解释为什么我收到此错误消息吗? Of 可以在整个应用程序中简单地使用 NSDictionary,但我更愿意继续使用 Swift 类型。

编辑:这是堆栈跟踪 stack trace

最佳答案

我终于明白了。

归档和取消归档机制工作正常。问题是我试图归档 [CarExtra: Int]? 类型的对象。所以我尝试归档一个可选的。如果您随后尝试将其转换为 [CarExtra : Int] (注意到缺少的了吗?)你会得到一个

EXC_BAD_INSTRUCTION(code=EXC_I386_INVOP, subcode = 0x0)

错误。

因此,解决方案是通过简单地解开包装来归档不是可选的 Swift 字典。确保字典不为零。为此,您可以使用 ??运算符

func encodeWithCoder(aCoder: NSCoder) {

    //make sure that the dictionary is not nil before
    aCoder.encodeObject(self.orderedExtras!, forKey: "orderedExtras")

}

注意!对对象进行编码时。 然后你可以将其转换回字典。

required convenience init?(coder aDecoder: NSCoder) {
      let extras = aDecoder.decodeObjectForKey("orderedExtras") as? [CarExtra : Int]
 }

关于swift - 取消归档 Swift 词典时的 EXC_BAD_INSTRUCTION,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34158997/

相关文章:

ios - Swift 中的 "mutating"函数和 "inout"参数有什么区别吗?

ios - 如何在 swift 中创建负的 Firebase 时间戳

ios - NSDictionary allKeys顺序

ios - NSCoding/NSKeyedArchiving 数据是否会通过主要的 iOS 更新保留?

ios - 如何将通用自定义对象保存到 UserDefaults?

swift - 如何在 swift 3 中发起 GET 请求

ios - 在 iPad 和 iPhone 之间更改表格 View 的行高大小

ios - 从 CGImageMetadata 转换为 nsdictionary

ios - swift: 将多个 <key, value> 对象添加到 NSDictionary

iOS - 取消归档具有日期类型属性的 NSSecureCoding 对象