Тип '[String, AnyObject?]' Не соответствует протоколу AnyObject?: почему?

Я пытаюсь понять, почему у меня ошибка компиляции: Тип '[String, AnyObject?]' не соответствует протоколу AnyObject?

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

Кажется, что cars не является AnyObject? которые я не понимаю.

Спасибо за вашу помощь!

Ответы

Ответ 1

AnyObject должен быть классом, но Dictionary является структурой.

Язык быстрого программирования: Тип Литье

AnyObject может представлять экземпляр любого типа класса.

Язык быстрого программирования: классы и структуры

Типы строк Swifts, Array и Dictionary реализуются как структуры.


Вы можете использовать Any? для этой цели.

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

Посмотрев на это немного больше, есть тонкая проблема, которая заставляет это сломаться.

Вот пример, который работает:

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

Это работает, потому что cars принудительно (неявно отбрасывается) от [String: AnyObject] к объекту, совместимому с NSDictionary ([NSObject: AnyObject]). Этот NSDictionary совместимый объект затем переносится на AnyObject. Итак, магия.

[String: AnyObject?] нельзя использовать таким образом, потому что он не поддерживает NSDictionary, поэтому принуждение не работает.

Ответ 2

Кажется, что автомобили - это не AnyObject?

Вы определили cars как тип [String: AnyObject?], таким образом, следующий код действителен (проверен на Playground):

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

Вы должны определить JSON как тип [String: AnyObject?] или [String: Any?] (в соответствии с вашими потребностями), только если вы не можете догадаться, какой тип cars будет (см. Type Casting для Any и AnyObject в языке Swift Programming).

Будет ли это влиять на кастинг моего объекта на NSDictionary?

NSDictionary не может содержать nil (здесь здесь или здесь). Следующий код выводит сообщение об ошибке на игровой площадке:

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

Однако, действует следующий код:

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