对字典键的复杂访问

Intricate access to dictionary key

我从服务器收到一个 JSON 字符串,然后我尝试以这种方式将其转换为 NSDictionary:

let JSON = try NSJSONSerialization.JSONObjectWithData(rToData!, options:[])
guard let JSONDictionary:NSDictionary = (JSON as! NSDictionary) else {
print("My grandma is way more NSDictionary than this")
return
}

转换后,我尝试获取字典中包含的一些数据:特别是我需要一个可以通过这种方式访问​​的数组:

let myArray = JSONDictionary["data1"][0]["data2"];

XCode 真的不喜欢这个想法,它在第一个括号下面放了一个箭头并说 可选类型 "AnyObject?" 的值未展开,你是想使用“!”要么 ”?” ?。我按照它的建议插入了一个“!”,将我前面的代码转换为:

let myArray = JSONDictionary["data1"]![0]["data2"];

此时,下一行(我计算data2中元素的数量)显示错误,指出AnyObject没有成员count

唯一似乎工作正常的是这个解决方案,但是,除了丑陋和不可读之外,我真的不明白它:

let myArray = (JSONDictionary["data1"]?[0]["data2"])!;

你能帮我理解为什么对字典中键的这种基本访问必须如此复杂吗?

我必须说我喜欢 Swift 但我花了很多时间处理可选和奇怪的 XCode 警报。

无法保证您的 JSON 字典将包含键 data1 的值(好的,您知道它会,但 Swift 不会)所以 JSONDictionary["data1"] returns 一个可选的。你需要用 ?要么 !

另外,因为你有一个 NSDictionary,而不是 Swift 字典,Swift 不知道值的类型,所以它们是 AnyObject。再一次,您知道它是一个数组,但 Swift 不是,因此您会收到一条错误消息,指出 AnyObject 没有 count 方法。

虽然比较冗长,但如果将行拆分为多行,编译器和其他查看代码的人都会更清楚。它还可以让您向下转换各种对象,以便 Swift 知道发生了什么并处理任何格式错误的 JSON;

if let array1 = JSONDictionary["data1"] as? NSArray {
   if let dictionary1 = array1[0] as? NSDictionary {
       if let data2Array = dictionary1["data2"] as? NSArray {
          let count=data2Array.count
       }
   }
}

您可以实施适当的 else 语句来处理错误

可选项是 Swift 最强大的功能之一。它们有助于避免与未初始化变量和边界条件的特殊标记值相关的一系列错误。重要的是您要了解他们如何帮助您,而不仅仅是扔东西?要么 !在你的代码中,直到它编译。