Swift下标错误

我相信它与可选项有关,但是我正在安全地解开sourceURL,所以我仍然不确定错误在哪里! 我试图访问一个JSON对象的数组的字典值。

但是,我仍然得到“无法find接受提供的参数'下标'重载。

这似乎很简单,但我似乎无法弄清楚!

var dictTemp: NSDictionary! = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: &localError) as? NSDictionary var finalURL: String // error line below if let sourceURL = dictTemp[0]["source"]["sourceUrl"] as? NSString { finalURL = sourceURL as String } 

从Swift访问NSDictionary是一个有趣的野兽。

只要Swift只知道某个东西是一个NSDictionary(不是一个更具体的[Key: Value] Swift风格的字典),你只能检索AnyObject? 出来了。

 let dictTemp: NSDictionary = // from somewhere... let step1 = dictTemp[0] // step1 is an AnyObject? 

但是,既然你已经导入了Foundation,你可以继续使用一个在AnyObject上工作的神奇的下标运算符,并检查这个东西是否是一个字典:

 let step2 = step1?["source"] // step2 is any AnyObject?? 

这是有趣的地方,因为

  • 如果step1是一个带有“source”键的字典, step2就是相应的值。
  • 如果step1是一个没有 “source”键的字典,那么step2将是nil – 尤其是AnyObject??.Some(AnyObject?.None)
  • 如果step1为零(原始字典没有0作为关键字),或者不是字典(它有一个其他types的值为0的关键字),那么step2将是nil – 特别是AnyObject??.None

(最后两种情况之间的区别大部分不重要,你不应该担心,但如果你感兴趣,你可以使用dump看到它)。

当然,我们可以再次运用同样的原则:

 let step3 = step2??["sourceUrl"] // step3 is AnyObject?? again 

现在, if

 if let url = dictTemp[0]?["source"]??["sourceUrl"] as? String { // do something with url... } 

警告

这种types的语法可能是危险的,因为它可以同时处理数组和字典。 你会在这些情况下期待什么?

 let dict: NSDictionary = [0: ["source": [3: "result"]]] dict[0]?["source"]??[3] // returns nil (surprise!) dict[0]?["source"]??[3 as NSNumber] // returns "result" let dict2: NSDictionary = [0: ["source": [8, 7, 6, 5, 4]]] dict2[0]?["source"]??[3] // returns 5 dict2[0]?["source"]??[3 as NSNumber] // returns nil (surprise!)