Swift:如果key不存在,decodeObjectForKey崩溃

时间:2015-03-06 13:52:29

标签: ios swift exc-bad-instruction

我使用以下Swift代码取消归档Swift类:

 required convenience init(coder decoder: NSCoder) {
    self.init()

    horseID = decoder.decodeIntegerForKey("horseID")
    name    = decoder.decodeObjectForKey("name") as String!

    // if the thumb key does not exist, the following line crashes
    thumb   = decoder.decodeObjectForKey("thumb") as UIImage!
}

"拇指"班级成员后来被添加。我有一个没有拇指数据的旧档案文件。 Apple的文档说,取消归档一个不存在的密钥会返回一个零。这是熟悉的Objective-C行为。我的Swift代码崩溃,错误代码为:EXC_BAD_INSTRUCTION(代码= EXC_I386_INVOP,子代码= 0x0)。

as更改为as?并不能解决问题。

这使得在新版本中扩展数据模型变得困难。难道我做错了什么?我是Swift的新手。

2 个答案:

答案 0 :(得分:2)

您正试图将其强制转换为UIImage,如果decodeObjectForKey返回nil,则会崩溃。您应该将as替换为as?以获取可选值,然后您可以检查它是否包含值。

如果thumb不是可选项,并且您使用decodeObjectForKey获得nil,则会收到错误消息EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0),即您在评论中提到的错误消息。你不能将nil分配给非可选的东西。您可以通过给它一个默认值来解决这个问题,如果类型转换会给你一个零:

thumb   = decoder.decodeObjectForKey("thumb") as? UIImage ?? [default value here]

答案 1 :(得分:2)

由于您表示未执行thumb的分配,我认为问题就在于行

name    = decoder.decodeObjectForKey("name") as String!

解码器可以返回nil,并且您正在强制转换为String。如果解码器在这种情况下返回nil,则会出现错误。我推荐这样的实现:

required convenience init(coder decoder: NSCoder) {
    self.init()

    horseID = decoder.decodeIntegerForKey("horseID")
    name    = decoder.decodeObjectForKey("name") as? String
    thumb   = decoder.decodeObjectForKey("thumb") as? UIImage
}

处理可能从编码器返回的nil值。