【问题标题】:Why is guard not protect me from nil为什么守卫不保护我免受零伤害
【发布时间】:2016-10-04 20:19:03
【问题描述】:

我使用 weatherAPI 进行某种 JSON 解析。为了防止我遇到 nullPointer(可能页面处于脱机状态或其他问题),我将我的解析覆盖到一个守卫中,因为我认为他保护我展开可选值。

guard
     let loadedWeather = (json["weather"] as! [[String:AnyObject]])[0]["description"] as? String,
     let loadedTemperatur = (json["main"] as! [String:AnyObject])["temp"] as? Float,
     let loadedWindSpeed = (json["wind"] as! [String:AnyObject])["speed"] as? Float
else {
     print("Weather JSON-Parsing failed")
     return
}

我误解了守卫的功能吗?如果是这样,我该如何解决这个问题? 实际上该页面处于脱机状态,并返回带有其他标签的错误 JSON 页面,例如“天气”、“主要”...等。不包括。我希望在那种情况下我的警卫能把我带到我的else 声明中,这样我就可以处理这种情况了。

非常感谢。

【问题讨论】:

    标签: json swift guard optional-values


    【解决方案1】:

    您误用了 guard 的语法 - 按如下方式使用:

    guard let weatherArray = json["weather"] as? [[String:AnyObject]], let mainDict = json["main"] as? [String:AnyObject], let windDict = json["wind"] as? [String:AnyObject] else {
        return
    }
    guard let dict = weatherArray.first else {
        return
    }
     guard let description = dict["description"] as? String, let temp = mainDict["temp"] as? Float, let speed = windDict["speed"] as? Float else {
        return
    }
    

    虽然我建议您遵循 Damien 概述的 if let 语法。

    【讨论】:

      【解决方案2】:

      您应该寻找条件展开:https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html

      if let weather = json["weather"] {
      // weather is define here, you can use it
      }
      

      【讨论】:

        【解决方案3】:

        改变

         as! [[String:AnyObject]]
        

         as? [[String:AnyObject]]
        

        您正在尝试强制转换您的 json 数据(as!),因此即使您使用保护,如果它为 nil,您仍然会在该位置发生崩溃。

        编辑:你说它仍然是强制的!所以也许尝试像这样拆分你的代码。还应该使您更容易从 json 响应的字典/数组中获取其他信息。像这样的东西应该可以工作

        /// Get json data
        guard
           let loadedWeather = json["weather"] as? [[String:AnyObject]],
           let loadedTemperatur = json["main"] as? [String:AnyObject],
           let loadedWindSpeed = json["wind"] as? [String:AnyObject]
           else {
             print("Weather JSON-Parsing failed")
             return
        }
        
        /// Get info from json data
        guard 
           let weatherDescription = loadedWeather[0]["description"] as? String,
           let temperature = loadedTemperatur["temp"] as? Float,
           let windSpeed = loadedWindSpeed["speed"] as? Float
           else {
             print("Weather JSON-Parsing failed")
             return
        }
        
         /// do something with weather description, temperature, windSpeed
        

        也许更好地尝试分别为每一行拆分这些保护语句,以防万一失败,您的整个块不会退出。在这种情况下,最好使用 if let ,因为您不想提前退出。只是不要用 if let 语句开始任何厄运金字塔。

        /// Weather
        if let loadedWeather = json["weather"] as? [[String:AnyObject]],
           let weatherDescription = loadedWeather[0]["description"] as? String {
              // do something with weather description
        }
        
        /// Temperature
        if let loadedTemperatur = json["main"] as? [String:AnyObject],
           let temperature = loadedTemperatur["temp"] as? Float {
             // do something with temperature
        }
        
        /// Wind speed
        if let loadedWindSpeed = json["wind"] as? [String:AnyObject],
           let windSpeed = loadedWindSpeed["speed"] as? Float {
             // do something with windspeed
        }
        

        希望这会有所帮助。

        【讨论】:

        • Swift 编译器强迫我这样做!
        • 构建失败了?
        • 你应该尝试拆分你的代码而不是做这个庞大的声明。让我更新我的答案,给我几分钟。
        • 我更新了我的答案。它还应该使您的代码更易于阅读。
        猜你喜欢
        • 2010-11-07
        • 2012-11-17
        • 1970-01-01
        • 1970-01-01
        • 2020-01-28
        • 2017-11-27
        • 2012-03-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多