Swift:输入字符串不';不符合任何对象的协议

Swift:输入字符串不';不符合任何对象的协议,swift,ios8,nsdictionary,Swift,Ios8,Nsdictionary,我可能错过了斯威夫特的一些基本内容。无法从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: "bu

我可能错过了斯威夫特的一些基本内容。无法从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 

它可以编译,但preferences对象设置为nil。

已找到。假设数组和NSArray相同,但事实并非如此

正确的说明是:

var preferences = settings.objectForKey("PreferenceSpecifiers") as NSArray

发现了。假设数组和NSArray相同,但事实并非如此

正确的说明是:

var preferences = settings.objectForKey("PreferenceSpecifiers") as NSArray

虽然很有趣,但恐怕你的答案并不能真正解决你的问题。转换为
NSArray
的原因是
NSArray
没有关联类型,而Swift的
数组有关联类型。以下是
数组
结构的相关摘要:

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
更接近你的情况:

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和Objective-C(文件): 阵列

Swift自动在阵列类型和NSArray之间建立桥接 班从NSArray对象桥接到Swift数组时 结果数组的类型为[AnyObject]。对象就是任何对象 兼容,如果它是Objective-C或Swift类的实例,或 如果对象可以桥接到一个。您可以桥接任何NSArray对象 因为所有Objective-C对象都是AnyObject 可共用的因为所有NSArray对象都可以桥接到Swift 数组,Swift编译器将NSArray类替换为[AnyObject] 当它导入Objective-CAPI时

将NSArray对象桥接到Swift数组后,还可以 将数组向下转换为更具体的类型。不同于从 NSArray类转换为[AnyObject]类型,从AnyObject向下转换为 更具体的类型不能保证成功。编译器无法执行此操作 直到运行时才能确定数组中的所有元素 可以向下转换为指定的类型。因此,向下投射 从[AnyObject]到[SomeType]返回可选值。例如 如果您知道Swift数组只包含UIView的实例 类(或UIView类的子类),可以向下转换数组 将任意对象类型元素添加到UIView对象数组中。如果有的话 Swift数组中的元素在运行时实际上不是UIView对象, 演员的成绩为零

字典

除了阵列之外,Swift还自动在 字典类型和NSDictionary类。当你从一个 NSDictionary对象到Swift字典,生成的字典为 类型为[NSObject:AnyObject]。您可以桥接任何NSDictionary对象 因为所有Objective-C对象都是AnyObject 可共用的回想一下,如果一个对象是一个 Objective-C或Swift类的实例,或者如果可以连接到 一所有NSDictionary对象都可以桥接到Swift字典,因此 Swift编译器将NSDictionary类替换为[NSObject: AnyObject]在导入Objective-C API时


虽然很有趣,但恐怕你的答案并不能真正解决你的问题。转换为
NSArray
的原因是
NSArray
没有关联类型,而Swift的
数组有关联类型。以下是
数组
结构的相关摘要:

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
更接近你的情况:

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和Objective-C(文件): 阵列

Swift自动在阵列类型和NSArray之间建立桥接 班从NSArray对象桥接到Swift数组时 结果数组的类型为[AnyObject]。对象就是任何对象 兼容,如果它是Objective-C或Swift类的实例,或 如果对象可以桥接到一个。您可以桥接任何NSArray对象 因为所有Objective-C对象都是AnyObject 可共用的因为所有NSArray对象都可以桥接到Swift 数组,Swift编译器将NSArray类替换为[AnyObject] 当它导入Objective-CAPI时

将NSArray对象桥接到Swift数组后,还可以 将数组向下转换为更具体的类型。不同于从 NSArray类转换为[AnyObject]类型,从AnyObject向下转换为 更具体的类型不能保证成功。编译器无法执行此操作 直到运行时才能确定数组中的所有元素 可以向下转换为指定的类型。因此,向下投射 从[AnyObject]到[SomeType]返回可选值。例如 如果您知道Swift数组只包含UIView的实例 类(或UIView类的子类),可以向下转换数组 将任意对象类型元素添加到UIView对象数组中。如果有的话 Swift数组中的元素在运行时实际上不是UIView对象, 演员的成绩为零

字典

除了阵列之外,Swift还自动在 字典类型和NSDictionary类。当你从一个 NSDictionary对象到Swift字典,生成的字典为 类型为[NSObject:AnyObject]。您可以桥接任何NSDictionary对象 因为所有Objective-C对象都是AnyObject 可共用的回想一下,如果一个对象是一个 Objective-C或Swift类的实例,或者如果可以连接到 一所有NSDictionary对象都可以桥接到Swift字典,因此 Swift编译器将NSDictionary类替换为[NSObject: AnyObject]在导入Objective-C API时