我使用以下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的新手。
答案 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
值。