假设您有一个json someText
字符串,并且您想将其解析为字典。以前我做过这个......
let jsonResult: NSDictionary =
try JSONSerialization.jsonObject(
with: someText.data(using: .utf8)!,
options: JSONSerialization.ReadingOptions.mutableContainers)
as! NSDictionary
但这只是一个糟糕的NSDictionary
。
看起来你确实可以这样做......
let jsonResult: [String:Any] =
try JSONSerialization.jsonObject(
with: someText.data(using: .utf8)!,
options: JSONSerialization.ReadingOptions.mutableContainers)
as! [String:Any]
所以现在它是一个真正的Swift词典。
这有用吗?是否存在激烈的效率差异,或者可能存在其他问题?
困惑地对我说,
open class func jsonObject(with data: Data,
options opt: JSONSerialization.ReadingOptions = []) throws -> Any
呼叫只会返回Any
。因此,当您将其投放到[String:Any]
或NSDictionary
时,过程是什么,最好的是什么?
答案 0 :(得分:4)
是否存在激烈的效率差异
是的。
NSDictionary
完全没有类型信息,本机Swift集合类型效率更高,强烈推荐。并且您使用var
免费获得可变性。无论如何,mutableContainers
在Swift中都是无用的。
jsonObject(with data
返回Any
,因为返回类型可以是Dictionary
,Array
甚至是String/Number
,最小公分母是Any
,把它投射到预期的类型。
答案 1 :(得分:3)
JSONSerialization.jsonObject(with:options:)
会返回NSDictionary
(如果是NSMutableDictionary
,则返回.mutableContainers
- 但这对于您的两个示例都是多余的)。
但是,由于根据解析的JSON数据类型可以返回其他类型,因此返回的静态类型为Any
。因此,您需要将此结果转换为字典类型,以便通知编译器您正在解析的数据实际上是一个有效的JSON对象(当然,如果您不确定这一事实,那么,应该conditionally cast来处理它不是的情况。
当谈到Swift词典时,可以使用两种存储方案 - native或Cocoa。在将结果转换为[String : Any]
的情况下,您使用Cocoa方案将NSDictionary
桥接到Swift词典 - 这并不比只是底层NSDictionary
的包装。
来自HashedCollections.swift.gyb:
// Cocoa storage uses a data structure like this:: // // Dictionary<K,V> (a struct) // +----------------------------------------------+ // | _VariantDictionaryBuffer<K,V> (an enum) | // | +----------------------------------------+ | // | | [ _CocoaDictionaryBuffer (a struct) ] | | // | +---|------------------------------------+ | // +-----|----------------------------------------+ // | // +---+ // | // V NSDictionary (a class) // +--------------+ // | [refcount#1] | // +--------------+
因此,就效率而言,在投射到NSDictionary
或[String : Any]
之间没有真正的区别。无论如何,您仍然使用NSDictionary
。
但是,作为@vadian has already said,当在Swift中工作时,原生的Swift词典总是优先于普通NSDictionary
,因为它们实际上携带有关其键的类型信息和值,编译器可以静态执行。