Swift:错误忽略了try语句

时间:2017-12-11 23:06:34

标签: swift error-handling swxmlhash

在我的代码中,我使用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?而不是抛出该错误。

有人可以帮忙吗?

2 个答案:

答案 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}}