简体   繁体   中英

Type '[String, AnyObject?]' does not conform to protocol AnyObject?: why?

I'm trying to understand why I have a compilation error: Type '[String, AnyObject?]' does not conform to protocol AnyObject?

var cars: [String: AnyObject?] = [ "model": "Ferrari"]
var JSON: [String: AnyObject?] = [ "cars": cars ]  // <-- error

It seems like cars is not an AnyObject? which I don't understand.

Thanks for your help!

AnyObject must be a class, but Dictionary is a structure.

The Swift Programming Language: Type Casting

AnyObject can represent an instance of any class type.

The Swift Programming Language: Classes and Structures

Swift's String, Array, and Dictionary types are implemented as structures.


You can use Any? for this purpose.

var cars: [String: Any?] = [ "model": "Ferrari"]
var JSON: [String: Any?] = [ "cars": cars ]

After looking at this a bit more, there is a subtle problem which causes this to break.

Here is a sample which works:

var cars: [String: AnyObject] = [ "model": "Ferrari"]
var JSON: [String: AnyObject] = [ "cars": cars ]

It works because cars is coerced (implicitly cast) from [String: AnyObject] to an object compatible with NSDictionary ([AnyHashable: AnyObject]) . This NSDictionary compatible object is then cast to AnyObject . So, magic.

[String: AnyObject?] cannot be cast in this way because it not NSDictionary compatible, so the coercion fails.

It seems like cars is not an AnyObject?

You defined cars as of type [String: AnyObject?] , thus, the following code is valid (tested in Playground):

var cars: [String: AnyObject?] = [ "model": "Ferrari"]
var JSON: [String: [String: AnyObject?]] = [ "cars": cars ]

You should define JSON as of type [String: AnyObject?] or [String: Any?] (according to your needs) only if you can't guess what type cars will be (see Type Casting for Any and AnyObject in The Swift Programming Language ).

Will that impact the casting of my object towards a NSDictionary?

NSDictionary can't hold nil (see here or here ). The following code gives an error message in Playground:

var nsDict1: NSDictionary = [12 : 10, 10 : nil] //eror message

var cars: [String: AnyObject?] = [ "model" : nil]
var JSON: [String: [String: AnyObject?]] = [ "cars" : cars ]
let nsDict2 = JSON as NSDictionary //error message

However, the following code is valid:

var nsDict1: NSDictionary = [12 : 10, 10 : NSNull()] //no error message

var cars: [String: AnyObject] = [ "model" : "Ferrari"] //also works with [ "model" : NSNull()]
var JSON: [String: [String: AnyObject]] = [ "cars" : cars ]

let nsDict2 = JSON as NSDictionary //no error message

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM