在我的代码中,我使用SWXMLHash库对一些XML进行反序列化。其grad.data.zero_()
方法在其声明中具有.value()
关键字,任何自定义反序列化函数也是如此。
我有以下代码行:
throws
由于该库不包含let myValue : UInt8 = try? xml["Root"]["ValueNode"].value()
的反序列化器,我已经定义了自己的:
UInt8
当节点具有值时,此方法有效。但是,当节点不存在或为零时,以下行会发生错误:
extension UInt8: XMLElementDeserializable {
public static func deserialize(_ element: XMLElement) throws -> UInt8 {
return UInt8(element.text)!
}
}
显然,这应该会发生。我不明白为什么我的return UInt8(element.text)! // Fatal error: Unexpectedly found nil while unwrapping an Optional value
语句没有捕获到此错误并返回try?
而不是抛出该错误。
有人可以帮忙吗?
答案 0 :(得分:1)
return UInt8(element.text)!
此行中没有try
。因此,这里不会抛出任何错误。如果UInt8
无法转换给定的字符串,则只返回nil
。然后,当然,您的!
会将nil
变成崩溃。
而不是那样做,而是做这样的事情:
guard let retVal = UInt8(element.text) else { throw SomeError }
return retVal
一般情况下:如果有办法使用!
做某事,而另一种方法是在不使用!
的情况下做同样的事情,除非你有一个很好的理由,否则去第二个
答案 1 :(得分:1)
并非所有错误都可以在Swift中捕获。如果使用throw Error
关键字标记函数,则表示该函数可能会抛出可恢复的错误。但是,您的自定义实现实际上并没有抛出任何错误。只有使用try?
关键字标记并使用代码try?
抛出的函数抛出的错误才能被do-catch块捕获。
nil
是一种将throwable函数的返回值转换为可选项的方法。如果函数会抛出错误,!
之后的值将为!
,否则它将是一个可选值。
当您使用deserialize
时,您明确告诉编译器您知道自己在做什么以及使用extension UInt8: XMLElementDeserializable {
public static func deserialize(_ element: XMLElement) throws -> UInt8 {
if let val = UInt8(element.text) {
return val
} else {
throw NSError(domain: "Couldn't deserialize value to UInt8", code: 1)
}
}
}
的操作是否失败,您的应用程序不应该正常失败。
您需要更改{{1}}方法以正常处理可选的展开或抛出错误。
{{1}}