【问题标题】:Checking Optionals for nil in Swift在 Swift 中检查 nil 的可选项
【发布时间】:2014-06-07 20:48:25
【问题描述】:

如何在 Swift 中检查 Optionals 的 nil 值?

我正在尝试评估解析 JSON 是否成功。这应该在传递无效 json 时打印一条错误消息,但由于 EXC_BAD_INSTRUCTION 失败。

func parseJson(data: NSData) {
    var error: NSError?
    var json: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error) as NSDictionary
    if let err = error {
        println("error parsing json")
        return
    }
    println("json parsed successfully")
}

尝试使用有效的 json 运行(工作正常):

parseJson(NSData(data: "{}".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)))

尝试使用无效的 json:

parseJson(NSData(data: "123".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)))

我是否错过了使用 Optionals 的要点?

【问题讨论】:

    标签: json swift


    【解决方案1】:

    发生崩溃是因为如果出现错误,JSONObjectWithData 返回 nil。然后,您尝试将 nil 转换为 NSDictionary。这有效:

    func parseJson(data: NSData) {
        var error: NSError?
        var json : AnyObject! = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error)
        if let err = error {
            println("error parsing json")
            return
        }
        println("json parsed successfully")
        var jsonDict = json as NSDictionary
    }
    

    如果您愿意,可以将 var json 的类型切换为 NSDictionary?所以它直接处理nil。为此,您只需添加一个“?”到“as”关键字这样:

    func parseJson(data: NSData) {
        var error: NSError?
        var json: NSDictionary? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error) as? NSDictionary
        if let err = error {
            println("error parsing json")
            return
        }
        // unwrap the optional value
        if let jsonDictionary = json {
            println("json parsed successfully")
            // use the dictionary
        }
    }
    

    【讨论】:

    • 我认为这个解决方案是最好的。它使用设计的 JSONObjectWithData API,并且是最简洁的。它展示了隐式解包选项的好处的一个很好的例子。
    【解决方案2】:

    我对您的代码进行了一些重组:

    func parseJson(data: NSData) {
        var error: NSError?
        var json: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error)
        if let jsonDict: NSDictionary = json as? NSDictionary{
            println("json parsed successfully")
            //do something with the nsdictionary...
        }
        else{
            println("error parsing json")
        }
    
    }
    parseJson(NSData(data: "{}".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)))
    parseJson(NSData(data: "123".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)))
    

    问题不在于您的 if 代码,而是在方法失败时使 json 不是一个 NSDictionary。此外,此代码现在检查是否返回了 NSDictionary,而不是检查错误本身。

    【讨论】:

      【解决方案3】:

      NSJSONSerialization.JSONObjectWithData 返回一个已隐式解包的可选值,这意味着返回值可以为 nil。在无效 JSON 情况下,返回 nil 可选类型。因此,您的 var json 也必须是可选类型,因为它可能为 nil。此外,如果var json 是可选类型,那么您必须通过在as 旁边添加? 将其向下转换为可选类型。这是最终结果

      var json: NSDictionary? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &error) as? NSDictionary
      

      【讨论】:

        【解决方案4】:

        在我将 NSDictionary 类型转换设为可选之前,我得到了 fatal error: unexpectedly found nil while unwrapping an Optional value,例如as? NSDictionary 而不是 as Dictionary

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-09-25
          • 1970-01-01
          • 2016-04-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-01
          相关资源
          最近更新 更多