读取info.plist:推断出类型AnyObject可能是意外的

sup*_*cio 4 casting info.plist ios swift

integer在我的info.plist文件中插入了一个,显然,我想从我的Swift中检索它UIViewController.代码很简单:

class MyController: UIViewController {

    private let value: Int

    required init(coder aDecoder: NSCoder) {

        if let info = NSBundle.mainBundle().objectForInfoDictionaryKey("v"){
            value = info.integerValue
        }else{
            value = 0
        }

        super.init(coder: aDecoder)
    }

    //other auto-generated-methods
    //...

}
Run Code Online (Sandbox Code Playgroud)

该函数objectForInfoDictionaryKey返回一个AnyObject?可选项,我很好.但编译器对我说

常量"info"推断为AnyObject可能是意外的

如何解决此警告,为什么我要担心函数返回AnyObject这一事实?< - 这是一个问号......哈哈

即使它返回AnyObject,如果对象不是,我也可以向下转换它nil.我不明白为什么编译器抱怨这个.

Mar*_*n R 12

Xcode通常会警告变量,这些变量被推断AnyObjectAnyObject?.您可以添加类型注释(如Xcode所示)以使警告静音:

if let info : AnyObject = ...
Run Code Online (Sandbox Code Playgroud)

我只能推测为什么 Xcode的行为是这样的,但有一个原因可能是你被"强迫"意识到info可能是任何对象类型而不是你期望的对象类型.

因此,即使info.integerValue 编译,如果对象不是预期类型,它也可能在运行时崩溃.在您的情况下,如果字典值不是a NSNumber或者NSString 然后info.integerValue抛出异常.

安全的方法是做一个可选的演员:

if let info = NSBundle.mainBundle().objectForInfoDictionaryKey("v") as? NSNumber {
    value = info.integerValue
} else {
    value = 0
}
Run Code Online (Sandbox Code Playgroud)

做到之间的自动重新映射NSNumber,Int你也可以写为

if let info = NSBundle.mainBundle().objectForInfoDictionaryKey("v") as? Int {
    value = info
} else {
    value = 0
}
Run Code Online (Sandbox Code Playgroud)

或者作为使用nil-coalescing运算符的单行??:

let value = NSBundle.mainBundle().objectForInfoDictionaryKey("v") as? Int ?? 0
Run Code Online (Sandbox Code Playgroud)