40

我有一个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。

4

6 回答 6

88

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

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

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

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!"按预期打印。

于 2014-06-03T23:29:50.863 回答
37

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

if sensor["latestValue"] is NSNull {
    // do something with null JSON value here
}
于 2016-06-02T07:11:07.647 回答
11

我正在使用这种组合,它还会检查 object 是否不是"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
}

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

于 2016-01-15T13:32:05.090 回答
9

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 的工作应用程序,并说明了完整的一般技术。

于 2014-06-19T16:28:33.593 回答
8

我现在的解决方案:

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

    return (someObject is NSNull)
}

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

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

于 2016-06-17T06:48:10.350 回答
3

我有一个非常相似的问题,并通过转换为原始 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 迅速关闭

于 2014-06-04T19:49:34.640 回答