【问题标题】:Swift double unwrapping of OptionalsOptionals 的 Swift 双重展开
【发布时间】:2015-03-30 16:29:27
【问题描述】:

我了解 Swift 中的可选项,但我只是遇到了一个“双重包装的可选项”,如果我不使用两个 '!' Xcode 会出现编译器错误

可选类型“字符串?”的值未拆封;你的意思是用'!'还是“?”?

我有以下代码,其中app 的类型为NSRunningApplication

let name: String = app.localizedName!

为什么我必须使用两个!?一个不足以解包变量,因为它是var localizedName: String? 类型。

背景: Xcode 要我使用let name: String = app.localizedName!!,否则会出现上面的编译器错误。 app 变量定义如下:

var apps = NSWorkspace().runningApplications.filter{$0.activationPolicy == NSApplicationActivationPolicy.Regular}
for app in apps{
    //code posted above
    …
}

所以我知道app 不是可选的,并且总是有一个值,也不是可选的应用程序。

附:使用快速枚举时有没有办法定义类型?比如for Foo(app) in appsapps = [AnyObject]

【问题讨论】:

  • app 究竟是如何定义的?会不会是一个可选的 NSRunningApplication?
  • 我们正在寻找答案,因为那行代码不应该产生那个错误。如果 app 是可选的,你会得到不同的错误。而localizedName 不是“双重可选”(笑)。这行代码看起来很好,不应该产生那个错误。不幸的是,Swift 会产生误导性的错误,我想知道真正的问题是否存在于较早的代码行中(或者您可能在准备问题时更改或清理了代码行)。另外,当我遇到莫名其妙的错误时,我会清理项目,退出 Xcode,清空派生数据文件夹,然后重新启动 Xcode。
  • @MartinR 添加了更多信息。为帮助干杯。

标签: xcode swift optional


【解决方案1】:

问题是NSWorkspace().runningApplications 返回一个 AnyObject 的数组必须转换为 NSRunningApplication:

let apps = NSWorkspace().runningApplications as! [NSRunningApplication]
let filteredApps = apps.filter {
        $0.activationPolicy == NSApplicationActivationPolicy.Regular
}
for app in apps {
    let name: String = app.localizedName!
}

【讨论】:

  • Xcode 显示上述代码的错误。您可能应该将as 替换为as!let apps = NSWorkspace().runningApplications as! [NSRunningApplication]
  • @Chris:你说得对,Swift 1.2 (Xcode 6.3) 改变了,谢谢你告诉我!
【解决方案2】:

原因如下:app 的类型为 AnyObject(在 Objective-C 中为 id),并且在 AnyObject 上进行任何查找都会引入一层可选性,因为该方法可能不存在于物体。 localizedName 本身是可选的,所以你最终会得到两个可选级别:如果对象不响应 localizedName,则外部级别为零,如果 'localizedName' 为 nil,则内部级别为零。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多