【问题标题】:Detect a Null value in NSDictionary在 NSDictionary 中检测 Null 值
【发布时间】:2014-06-03 23:24:43
【问题描述】:

我有一个NSDictionary,它是从 API 服务器的 JSON 响应中填充的。有时,此字典中某个键的值是 Null

我正在尝试获取给定的值并将其放入表格单元格的详细文本中以进行显示。

问题是,当我尝试将值强制转换为 NSString 时,我遇到了崩溃,我认为是因为我试图将 Null 强制转换为字符串。

这样做的正确方法是什么?

我想做的是这样的:

cell.detailTextLabel.text = sensor.objectForKey( "latestValue" ) as NSString

这是字典的一个例子:

Printing description of sensor:
{
    "created_at" = "2012-10-10T22:19:50.501-07:00";
    desc = "<null>";
    id = 2;
    "latest_value" = "<null>";
    name = "AC Vent Temp";
    "sensor_type" = temp;
    slug = "ac-vent-temp";
    "updated_at" = "2013-11-17T15:34:27.495-07:00";
}

如果我只需要将所有这些都包含在条件中,那很好。我只是无法弄清楚那个条件是什么。回到 Objective-C 世界,我会与 [NSNull null] 进行比较,但这似乎不适用于 Swift。

【问题讨论】:

  • NSNull 该类存在于 Swift 中,因此您可以与 NSNull() 进行比较

标签: ios swift nsnull


【解决方案1】:

您可以使用as? 运算符,它返回一个可选值(nil 如果向下转换失败)

if let latestValue = sensor["latestValue"] as? String {
    cell.detailTextLabel.text = latestValue
}

我在一个 swift 应用程序中测试了这个例子

let x: AnyObject = NSNull()
if let y = x as? String {
    println("I should never be printed: \(y)")
} else {
    println("Yay")
}

它正确打印"Yay",而

let x: AnyObject = "hello!"
if let y = x as? String {
    println(y)
} else {
    println("I should never be printed")
}

按预期打印"hello!"

【讨论】:

  • 即使他的值实际上是NSNull 的一个实例,这是否有效?
  • @TimGostony 除非 as? 规范具有误导性,是的,它会起作用,因为演员表会失败。
  • 使用 downcast 时,我在 Playground 中收到关于 as? 用法的错误:Could not find an overload for 'subscript' that accepts the supplied arguments
  • @TimGostony 我在一个应用程序中尝试过,它似乎可以工作。
  • 您是否尝试过从字典中获取对象?
【解决方案2】:

您也可以使用is 来检查是否存在空值:

if sensor["latestValue"] is NSNull {
    // do something with null JSON value here
}

【讨论】:

    【解决方案3】:

    我正在使用这个组合,它还会检查对象是否不是"null"

    func isNotNull(object: AnyObject?) -> Bool {
        guard let object = object else { return false }
        return isNotNSNull(object) && isNotStringNull(object)
    }
    
    func isNotNSNull(object: AnyObject) -> Bool {
        object.classForCoder != NSNull.classForCoder()
    }
    
    func isNotStringNull(object: AnyObject) -> Bool {
        guard let object = object as? String where object.uppercaseString == "NULL" else {
            return true
        }
        return false
    }
    

    它不像扩展那么漂亮,但可以作为魅力:)

    【讨论】:

      【解决方案4】:

      NSNull 是一个和其他类一样的类。因此,您可以使用isas 来测试针对它的 AnyObject 引用。

      因此,在我的一个应用程序中,我有一个 NSArray,其中每个条目都是 Card 或 NSNull(因为您不能将 nil 放入 NSArray)。我将 NSArray 作为一个数组获取并循环遍历它,打开我得到的对象类型:

      for card:AnyObject in arr {
          switch card { // how to test for different possible types
          case let card as NSNull:
              // do one thing
          case let card as Card:
              // do a different thing
          default:
              fatalError("unexpected object in card array") // should never happen!
          }
      }
      

      这与您的场景不同,但它来自转换为 Swift 的工作应用程序,并说明了完整的一般技术。

      【讨论】:

        【解决方案5】:

        我现在的解决方案:

        func isNull(someObject: AnyObject?) -> Bool {
            guard let someObject = someObject else {
                return true
            }
        
            return (someObject is NSNull)
        }
        

        到目前为止,测试看起来不错...

        【讨论】:

          【解决方案6】:

          我有一个非常相似的问题,并通过转换为原始 NSDictionary 值的正确类型来解决它。如果你的服务返回一个像这样的混合类型 JSON 对象

          {"id":2, "name":"AC Vent Temp", ...}
          

          你必须像这样获取它的值。

          var id:int = sensor.valueForKey("id") as Int;
          var name:String? = sensor.valueForKey("name") as String;
          

          这确实解决了我的问题。见BAD_INSTRUCTION within swift closure

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-12-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-10-02
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多