Swift Subscript Error

只谈情不闲聊 提交于 2019-12-12 21:43:46

问题


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

        }

回答1:


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!)


来源:https://stackoverflow.com/questions/31623244/swift-subscript-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!