我可能错过了一些基本的东西。无法从NSDictionary值中获取数组。
代码是:
import Foundation
//need to add Settings bundle to project in order to run this test.
class CompileError {
func foo(){
let path = NSBundle.mainBundle().pathForResource("Settings", ofType: "bundle");
if(path == nil) {
NSLog("Could not find Settings.bundle");
return;
}
let settings:NSDictionary = NSDictionary(contentsOfFile:path!.stringByAppendingPathComponent("Root.plist"));
var preferences:Array = settings.objectForKey("PreferenceSpecifiers") as Array //Get Compile Error: type String doesn't conform to protocol AnyObject
}
}
在调试器中看到,Preferences对象有一个用于键" PreferenceSpecifiers"的数组,但我无法施放它。 如果我尝试:
var preferences:Array = settings.objectForKey("PreferenceSpecifiers")?.Array
它编译但是首选项对象设置为nil。
答案 0 :(得分:4)
虽然很有趣,但我担心你的答案并不能解决你的问题。转换为NSArray
“工作”的原因是因为NSArray
没有关联的类型,而Swift的Array
会这样做。 Array
struct 的相关摘要如下:
struct Array<T> : MutableCollectionType {
typealias Element = T
init<S : SequenceType>(s: S)
// and much more – just Command-click on `Array` and check it out for yourself
显然,Array
是一个通用的struct集合,即只有当Element
s(或T
s)的类型已知时,才会完全指定其类型。所以as NSArray
并不是“正确的指令”,因为它推迟了掌握仿制药所需的时间。然而,这应该是愉快和有益的,因为作为一种语言,斯威夫特是新的,并且正在蓬勃发展和非常古老和经验丰富,继承了许多其他语言的所有好东西... < / p>
简而言之:
let arr: NSArray = [1,2,3,4,5]
// even after casting to `NSArray`, `arr` is still an `[AnyObject]`
// e.g. try this:
// arr is [AnyObject] // compiler error: 'is' test is always true
let ints = arr as [Int] // --> [1,2,3,4,5]
// or more safely:
if let ints = arr as? [Int] {
ints // --> [1,2,3,4,5]
}
更贴近您的情况:
let array: NSArray = ["settings", "etc", "..."] // just simulating the objects you are working with
let settings: NSDictionary = ["PreferenceSpecifiers": array] // ditto
if let prefs = settings["PreferenceSpecifiers"] as? [String] {
prefs // --> ["settings", "etc", "..."]
// this is only if *all* PreferenceSpecifiers are NSStrings,
// otherwise, you'll have to downcast them as an when you access them
// rather than wholesale, as I did here...
} else {
// ouch, no preferences found
}
<强>阵列强>
Swift自动在Array类型和NSArray之间架起桥梁 类。当您从NSArray对象桥接到Swift数组时, 结果数组的类型为[AnyObject]。对象是AnyObject 如果它是Objective-C或Swift类的实例,则兼容,或者 如果对象可以桥接到一个。您可以桥接任何NSArray对象 到Swift数组,因为所有Objective-C对象都是AnyObject 兼容。因为所有NSArray对象都可以桥接到Swift 数组,Swift编译器用[AnyObject]替换NSArray类 何时导入Objective-C API。
将NSArray对象桥接到Swift数组后,您也可以 将数组转换为更具体的类型。与铸造不同 NSArray类为[AnyObject]类型,从AnyObject向下转换为 更具体的类型不能保证成功。编译器不能 直到运行时才知道数组中的所有元素 可以下载到您指定的类型。结果,向下倾斜 从[AnyObject]到[SomeType]返回一个可选值。例如, 如果你知道Swift数组只包含UIView的实例 class(或UIView类的子类),您可以向下转换数组 AnyObject类型元素到UIView对象的数组。如果有的话 Swift数组中的元素在运行时实际上不是UIView对象, 演员回归无。
<强>字典强>
除了数组之外,Swift还自动桥接了 字典类型和NSDictionary类。当你从一个桥梁 NSDictionary对象是一个Swift字典,结果字典是 类型为[NSObject:AnyObject]。您可以桥接任何NSDictionary对象 到Swift字典,因为所有Objective-C对象都是AnyObject 兼容。回想一下,如果一个对象是AnyObject兼容的 Objective-C或Swift类的实例,或者它是否可以桥接到 一。所有NSDictionary对象都可以桥接到Swift词典,所以 Swift编译器用[NSObject:替换NSDictionary类: AnyObject]在导入Objective-C API时。
答案 1 :(得分:1)
发现了。假设Array与NSArray相同,并且它不是。
正确的说明是:
var preferences = settings.objectForKey("PreferenceSpecifiers") as NSArray