问题描述
我相信它与可选项有关,但我安全地解开了sourceURL,所以我仍然不知道错误在哪里!我正在尝试访问一个JSON对象的数组的字典值。然而,我仍然得到无法找到接受提供的参数的'subscript'的重载
看起来很简单,但我似乎无法想像出来!
var dictTemp:NSDictionary!= NSJSONSerialization.JSONObjectWithData(data !, options:NSJSONReadingOptions.MutableContainers,error:& localError)as?NSDictionary
var finalURL:String
//错误行以下
如果让sourceURL = dictTemp [0] [source] [sourceUrl] as?NSString {
finalURL = sourceURL as String
}
从Swift访问的NSDictionary是一个有趣的野兽。
$ b $只要Swift只知道一些是NSDictionary(不是一个更具体的 [Key:Value]
Swift风格的字典),你只能检索 A nyObject?
出来。 let dictTemp:NSDictionary = // from somehere ...
let step1 = dictTemp [0] // step1是一个AnyObject?但是,由于你已经导入了Foundation,所以你可以继续使用一个神奇的下标运算符在 AnyObject
,并检查是否是字典: let step2 = step1?[source] // step2是AnyObject?
这里是有趣的地方,因为
- 如果
step1
是一个字典,其中有一个源键, step2
将作为相应的值。
- 如果
step1
是没有 的字典 source键, step2
将是 nil
- 特别是它的 AnyObject?一些(AnyObject?.None)
。
- 如果
step1
为零(原始字典没有有0作为键),或不是字典(它有一个0键与其他类型的值),然后 step2
将是 nil
- 特别是 AnyObject?。无
。
(最后2个案例之间的区别大多不重要,你不应该担心,但是如果你有兴趣,可以使用 dump
看到它)。
当然,我们可以再次应用相同的原则:
let step3 = step2 ?? [sourceUrl] // step3是AnyObject?再次
现在,将它们全部绑定在一个中,如果
:
如果let url = dictTemp [0]?[source] ?? [sourceUrl] as?字符串{
//使用url ...做某事...
}
警告
这种类型的语法可能是危险的,因为它与数组和字典同时使用。在这些情况下你会期待什么?
let dict:NSDictionary = [0:[source:[3:result ]]]
dict [0]?[source] ?? [3] //返回nil(惊喜!)
dict [0]?[source]? ?[3 as NSNumber] //返回result
let dict2:NSDictionary = [0:[source:[8,7,6,5,4]]]
dict2 [0]?[source] ?? [3] //返回5
dict2 [0]?[source] ?? [3 as NSNumber] //返回nil !)
I believe it has something to do with optionals, but I'm safely unwrapping sourceURL so I'm still not sure where the error is! I'm trying to access a JSON object's array's dictionary value.
However, I'm still getting the "could not find overload for 'subscript' that accepts the supplied arguments.
It seems simple, but I just can't seem to figure it out!
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
}
解决方案 NSDictionary accessed from Swift is an interesting beast.
As long as Swift only knows something is an NSDictionary (not a more specific [Key: Value]
Swift-style dictionary), you can only retrieve AnyObject?
s out of it.
let dictTemp: NSDictionary = // from somewhere...
let step1 = dictTemp[0] // step1 is an AnyObject?
But then, since you've imported Foundation, you can keep going with a magical subscript operator that works on AnyObject
, and checks whether the thing is a dictionary:
let step2 = step1?["source"] // step2 is any AnyObject??
Here's where it gets interesting, because
- if
step1
was a dictionary with a "source" key inside it, step2
will be the corresponding value. - if
step1
was a dictionary without a "source" key, step2
will be nil
— in particular, it's AnyObject??.Some(AnyObject?.None)
. - if
step1
was nil (the original dictionary didn't have 0 as a key), or not a dictionary (it had a 0 key with some other kind of value), then step2
will be nil
— in particular, AnyObject??.None
.
(The distinction between the last 2 cases is mostly unimportant and you shouldn't worry about it, but if you're interested you can see it by using dump
).
And of course, we can apply the same principle again:
let step3 = step2??["sourceUrl"] // step3 is AnyObject?? again
Now, binding them all in one if
:
if let url = dictTemp[0]?["source"]??["sourceUrl"] as? String {
// do something with url...
}
Caveat
This type of syntax can be dangerous, since it works with arrays and dictionaries at the same time. What would you expect in these situations?
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!)
这篇关于Swift下标错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!