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

我正在使用下面的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! } 

稍后添加“拇指”类成员。 我有一个没有拇指数据的旧档案文件。 苹果的文档说,取消存档不存在的密钥返回零。 这是熟悉的Objective-C行为。 我的Swift代码崩溃,错误代码为:EXC_BAD_INSTRUCTION(code = EXC_I386_INVOP,subcode = 0x0)。

as? 并没有消除这个问题。

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

你试图强制将它转换成UIImage,如果decodeObjectForKey返回nil,将会崩溃。 你应该更换as? 得到一个可选的值,然后你可以检查它是否包含一个值。

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

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

既然你表示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值。