取消归档Swift词典时的EXC_BAD_INSTRUCTION

时间:2015-12-08 14:56:09

标签: swift nsdictionary nscoding nskeyedarchiver

我正在尝试取消归档实现NSCoding协议的自定义对象。这个类名为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(代码= EXC_I386_INVOP,子代码= 0x0)

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

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

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

编辑:这是堆栈跟踪 stack trace

1 个答案:

答案 0 :(得分:1)

我终于明白了。

归档和取消归档机制运行良好。问题是我试图归档[CarExtra: Int]?类型的对象。所以我试着归档一个Optional。如果你然后尝试将它作为[CarExtra : Int]投射(注意缺失?),你会得到一个

  

EXC_BAD_INSTRUCTION(代码= EXC_I386_INVOP,子代码= 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]
 }