在SWIFT中,您是否可以捕获在展开可选值&时意外发现nil的致命错误? [英] In Swift can you trap "fatal error unexpectedly found nil while unwrapping an optional value"?

查看:34
本文介绍了在SWIFT中,您是否可以捕获在展开可选值&时意外发现nil的致命错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在解析一个NSDictionary。我不想一项一项地检查,以确保一切都是真实的,没有什么出乎意料地是空的。我想我只需要做-试-接。但我收到了一个编译器警告。以下是我的代码:说:

do {
    try adminMsg = NSDictionary(objects: [rawMsg["msg"]!["Title"]!!,
                                          rawMsg["msg"]!["Text"]!!,
                                          rawMsg["msg"]!["Time"]!!],
                                      forKeys: ["Title", "Text", "Time"])
} catch {
    adminMsg = nil
}

但我收到以下警告:

"在‘try’表达式中没有对抛出函数的调用"

这是否意味着,如果词典中缺少某个项目,我别无选择,只能崩溃?我不能捕获它并让我的代码优雅地告诉发送者他们给我发送了无效的NSD词典(除非我在代码中逐项签出它)?

推荐答案

我无法捕获它并让我的代码优雅地告诉发送者,他们向我发送了无效的NSDictionary

无法捕获致命错误,否。您可以通过使用可选绑定来捕获缺少的元素。

guard let title = message["Title"],
      let text = message["Text"],
      let time = message["Time"]
else {

    // Missing data; inform caller
}

这是您优雅地告诉客户端数据有问题的方式。您可以返回nil、空词典或抛出错误:最适合您的那个。

要使其正确快捷,您应该首先定义数据:

typealias RawMessage = Dictionary<String, [String : AnyObject]>

/** Important keys in a `RawMessage` */
enum RawMessageKey : String
{
    case message = "msg"
    case title = "Title"
    case text = "Text"
    case time = "Time"
}

enum RawMessageError : ErrorType 
{
    /** The `RawMessage` has no "message" key */
    case NoMessage
    /** The `RawMessage` is missing an expected inner key */
    case MissingKey
}

然后是您的提取函数。这使用可选绑定而不是强制展开来检查密钥"msg"是否存在。无法"捕获"强制展开失败;这不是它的用途。

如果键不存在,则通过抛出您自己的错误来向调用者发出信号。然后使用进一步的可选绑定来获取其余的项。如果缺少任何错误,则再次引发错误。

/** Pull important values from `RawMessage` and repackage as `NSDictionary` */
func extractAdminMessage(rawMsg: RawMessage) throws -> NSDictionary 
{
    guard let message = rawMsg[String(RawMessageKey.message)] else {
        throw RawMessageError.NoMessage
    }

    let keys = [String(RawMessageKey.title), 
                String(RawMessageKey.text), 
                String(RawMessageKey.time)]

    guard let title = message[String(RawMessageKey.title)],
          let text = message[String(RawMessageKey.text)],
          let time = message[String(RawMessageKey.time)]
    else {

        throw RawMessageError.MissingKey
    }

    return NSDictionary(objects: [title, text, time],
                        forKeys: keys)
}

如果您愿意,可以使用flatMap替代堆叠解除绑定:

let keys = [String(RawMessageKey.title), 
            String(RawMessageKey.text), 
            String(RawMessageKey.time)]

let objects = keys.flatMap { message[$0] }

guard objects.count == keys.count else {
    throw RawMessageError.MissingKey
}

在这里,任何缺少的值都将被flatMap删除;然后,如果没有与对象相同数量的键,则向调用者发出信号。

这篇关于在SWIFT中,您是否可以捕获在展开可选值&时意外发现nil的致命错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆