在 NSDictionary 中检测 Null 值

Posted

技术标签:

【中文标题】在 NSDictionary 中检测 Null 值【英文标题】:Detect a Null value in NSDictionary 【发布时间】: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() 进行比较 【参考方案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

【讨论】:

以上是关于在 NSDictionary 中检测 Null 值的主要内容,如果未能解决你的问题,请参考以下文章

RestKit NSDictionary 映射 NULL 值

NSDictionary 检查 null

NSDictionary 具有空值

NSDictionary 转换后显示 null

从 NSDictionary 传递的 iOS 数据为 (null) - JSON 源

将选择器作为值存储在 NSDictionary 中