选项的保护语句在 swift 中为零

Posted

技术标签:

【中文标题】选项的保护语句在 swift 中为零【英文标题】:Guard statements for optionals are nil in swift 【发布时间】:2016-03-02 17:26:16 【问题描述】:

我正在使用来自天气 API 的 SwiftyJson 解析 json 数据。我有一个可选数据列表,我将其添加到单个保护语句中,以使代码看起来更简单、更有效。但不幸的是,在选项列表中,我有时会从已解析的 API 数据中获得 nil 值,因此该语句转到 else 并且不返回任何内容。我是否必须将保护 else 语句放在每个可选语句中,或者有一种方法可以继续并在 else 语句中返回找到的非 nil 值?

这是我的代码:

dispatch_async(dispatch_get_main_queue(), 
                 let jsonContent = JSON(data: data!)

                 guard  let cTemp = jsonContent["currently"]["temperature"].double,
                        let cFeelsLike = jsonContent["currently"]["apparentTemperature"].double,
                        let cHumidity = jsonContent["currently"]["humidity"].double,
                        let cDewPoint = jsonContent["currently"]["dewPoint"].double,
                        let cPressure = jsonContent["currently"]["pressure"].double,
                        let cVisibility = jsonContent["currently"]["visibility"].double,
                        let cWindSpeed = jsonContent["currently"]["windSpeed"].double,
                        let cWindDirection = jsonContent["currently"]["windBearing"].double,
                        let cRainChance = jsonContent["currently"]["precipProbability"].double,
                        let cIconString = jsonContent["currently"]["icon"].string,
                        let cSummary = jsonContent["currently"]["summary"].string,
                        let cDailySummary = jsonContent["daily"]["summary"].string

                        else

                            self.messageFrame.removeFromSuperview()
                          return
                        

这是解析数据后更改情节提要上的标签的代码。

 if self.segmentedControl.selectedSegmentIndex == 0 
                    UIApplication.sharedApplication().applicationIconBadgeNumber = Int(round(cTemp))
                    self.tempLabel.text = String(Int(round(cTemp))) + "˚"
                    self.humidityLabel.text = String(Int(round(cHumidity*100))) + "%"
                    self.pressureLabel.text = String(Int(round(cPressure))) +  NSLocalizedString(" mBar", comment: "milli Bar")
                    self.windSpeedLabel.text = String(Int(round(cWindSpeed))) + NSLocalizedString(" Km/h", comment: "Kilo fe El sa3a")
                    self.realFeelLabel.text = String(Int(round(cFeelsLike))) + "˚"
                    self.windDirectionLabel.text = self.windDirectionNotation(cWindDirection)
                    self.rainChanceLabel.text = String(Int(round(cRainChance * 100))) + "%"
               //     self.visibilityLabel.text = String(Int(round(cVisibility))) + NSLocalizedString(" Km", comment: "Km")
                    self.descriptionLabel.text = cSummary
                    self.descriptionMoreLabel.text = cDailySummary
                    self.bgImage.image = self.bgPicker(cIconString) //Change BG according to currently weather conditions.

                 else 
                    self.tempLabel.text = String(Int(round(cTemp))) + "˚"
                    self.humidityLabel.text = String(Int(round(cHumidity*100))) + "%"
                    self.pressureLabel.text = String(Int(round(cPressure))) + NSLocalizedString(" mBar", comment: "milli Bar")
                    self.windSpeedLabel.text = String(Int(round(cWindSpeed))) + NSLocalizedString(" mph", comment: "meel fee el sa3a")
                    self.realFeelLabel.text = String(Int(round(cFeelsLike))) + "˚"
                    self.windDirectionLabel.text = self.windDirectionNotation(cWindDirection)
                    self.rainChanceLabel.text = String(Int(round(cRainChance * 100))) + "%"
              //      self.visibilityLabel.text = String(Int(round(cVisibility))) + NSLocalizedString(" mi", comment: "meel")
                    self.descriptionLabel.text = cSummary
                    self.descriptionMoreLabel.text = cDailySummary
                    self.bgImage.image = self.bgPicker(cIconString) //Change BG according to currently weather conditions.
                

【问题讨论】:

如果其中一个选项为 nil,你想做什么?换句话说:如果您不想中止,为什么要首先测试所有这些值?您的cTemp 等纯粹是局部变量,您没有对它们做任何事情,那么您的代码的目的是什么? 我想忽略它并继续操作。在情节提要标签上发布当前找到的数据。或者也许我必须尝试将所有剩余的代码放在 else 语句中?但数据将不完整。因为它在检查保护语句中找到的所有选项之前返回。 好的,很酷。那么你在哪里做那部分呢?如果你需要帮助重写你的代码,你需要展示你的那部分代码。 @Matt 例如,当我注释掉可见性可选代码时,代码运行良好,但当可见性数据为零时,它什么也不返回,故事板上的标签也没有改变。 是的,但是您没有显示任何更改任何标签的代码。我要求你展示它。 【参考方案1】:

将标签的text 设置为 nil 或可选字符串是合法的。所以对于每一项,使用 Optional chaining 来解包,并设置对应标签的text

不幸的是,我不知道 SwiftyJSON,但如果这只是一个字典,你会这样做:

// here is some test data
let content = ["currently":["temperature":"21"]]
let lab = UILabel()
// this is what you would do
lab.text = (content["currently"] as? NSDictionary)?["temperature"] as? String

重点是最后一行。如果我们得到nil,我们将标签的text 设置为nil,不会造成任何伤害。如果我们得到我们的字符串,我们将标签的text 设置为包裹该字符串的 Optional 并且不会造成任何伤害。

【讨论】:

好的,您的意思是在每个可选语句之后立即更改标签?如果他们是 nil ,则不会造成任何伤害。 没错,但不幸的是,我无法准确告诉您使用 SwiftJSON 执行此操作的语法。 嗨@matt:这是 SwiftyJSON 的语法:json["currently"]["temperature"].double。这个库的美妙之处在于您可以安全地浏览 JSON。如果您访问一个不存在的键,当您尝试将相关值转换为支持的类型之一(DoubleInt、...)时,您只需获得一个 nil 值。

以上是关于选项的保护语句在 swift 中为零的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 json 编码对象在 Swift 中为零

navigationController 在 swift 中为零

self.navigationController 在 swift 中为零

自定义类 Unarchive 在 Cocoa Swift 中为零

RestKit:映射类在 Swift 中为零

!= nil 语句中的 Swift 选项[重复]