Swift:如果键不存在,则 decodeObjectForKey 崩溃
Posted
技术标签:
【中文标题】Swift:如果键不存在,则 decodeObjectForKey 崩溃【英文标题】:Swift: decodeObjectForKey crashes if key doesn't exist 【发布时间】:2015-03-06 13:52:28 【问题描述】:我正在使用以下 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!
后来添加了“thumb”类成员。我有一个较旧的存档文件,其中没有拇指数据。 Apple 的文档说,取消归档不存在的密钥会返回 nil。这是熟悉的 Objective-C 行为。我的 Swift 代码崩溃并出现错误代码:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)。
从as
更改为as?
并不能解决问题。
这使得在新版本中扩展数据模型变得困难。难道我做错了什么?我是 Swift 新手。
【问题讨论】:
as UIImage!
是强制转换,如果返回值为 nil 会崩溃。您是否尝试过可选演员 as? UIImage
?
thumb = decoder.decodeObjectForKey("thumb") as? UIImage 也会崩溃
您是否设置了调试停止并检查了thumb
的内容?
未执行对 thumb 的分配。在此之前代码崩溃。
@ThomasZimmer 这似乎很棘手,您能在某处提供源代码并在此处分享链接吗?
【参考方案1】:
您试图将其强制转换为 UIImage,如果 decodeObjectForKey 返回 nil,它将崩溃。您应该将as
替换为as?
以获得可选值,然后您可以检查它是否包含值。
如果 thumb 不是可选的,并且您使用 decodeObjectForKey 得到 nil,您将收到错误消息 EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
,即您在 cmets 中提到的错误消息。您不能将 nil 分配给非可选内容。你可以通过给它一个默认值来解决这个问题,以防类型转换会给你一个 nil:
thumb = decoder.decodeObjectForKey("thumb") as? UIImage ?? [default value here]
【讨论】:
我在 Martin R 的评论之后尝试过,但结果是一样的 - 崩溃。 @ThomasZimmer 它是否因相同的错误消息而在同一行崩溃?您能在此处提供完整的错误消息吗? EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) 是确切的错误 你有没有尝试在分配名称时更改为as?
?因为如果将 thumb nil 分配给它,它确实不应该崩溃,除非 thumb 不是可选的。
alkku,“拇指”是可选的。正如你提到的那样改变线路并没有改变奇怪的崩溃。【参考方案2】:
由于您表示未执行对thumb
的分配,我相信问题出在这条线
name = decoder.decodeObjectForKey("name") as String!
解码器可以返回nil
,并且您正在强制转换为字符串。如果解码器在这种情况下返回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
值。
【讨论】:
sbooth,不,第一行(“名称”从解码器中出来)被正确执行。所以问题在于从解码器分配“拇指”值的行。更改“作为 UIImage!”进入“as?UIImage”再次导致崩溃。 即便如此,如果由于某种原因decoder
不包含name
的值,我相信强制转换也会发生类似的崩溃。以上是关于Swift:如果键不存在,则 decodeObjectForKey 崩溃的主要内容,如果未能解决你的问题,请参考以下文章