如何在一个表达式中检查Optional是否为nil且属性为true?

时间:2014-06-27 19:49:58

标签: swift

使用Swift,我有NSStatusItem,当我点击它时,我想检查NSWindow是否可见。如果是,则将其隐藏,如果不是,则调用函数以显示NSWindow

我的NSWindow是我的应用代表var window: NSWindow?中的一个类属性。在响应单击NSStatusItem的方法中,我尝试使用Optional Chaining执行以下操作:

if self.window?.visible {
    self.window!.orderOut(self) // or self.window?.orderOut(self), same behavior
}
else {
    displayWindow()
}

但是,如果window nil,则每次都会进入if块。如果window nil,则每次都会进入else块。换句话说,这似乎不起作用。我无法检查window是否不是nil,并且window是否在一个表达式中可见。 (我认为这是使用Optional Chaining的一个显而易见的地方。)

我试过这个,看看会发生什么:

if self.window!.visible {
    self.window!.orderOut(self)
}
else {
    displayWindow()
}

如果window nil,则有效。首先隐藏window,因此它会点击else块并显示窗口。下次调用该方法时,window是可见的,因此它会执行else块。等等。正是我想要的,除了我无法检查windownil。如果是nil,我会明显崩溃“fatal error: Can't unwrap Optional.None

以下内容允许我检查window是否为nil,然后检查它是否可见:

if let win = self.window {
    if win.visible {
        win.orderOut(self)
    } else {
        displayWindow()
    }
}
else {
    NSLog("self.window == nil")
}

然而,这是罗嗦的,我真的认为我应该能够做到第一。我真的必须以第三种方式做到这一点吗?或者我是否正确假设第一个案例不起作用是一个错误?

编辑:这种方式也有效:

if self.window && self.window!.visible {
    self.window?.orderOut(self)
}
else {
    displayWindow()
}

但同样,不是可选链接意味着要取代这种东西吗?

1 个答案:

答案 0 :(得分:3)

修改

Cezar的解决方案(下面的第一条评论)证明更为正确:

self.window?.visible == true

我的解决方案存在严重缺陷。如果self.windownil,则会尝试解包nil并崩溃。

- 旧答案 -

正如我的评论所述:

使用Optional Chaining时,返回的值始终为Optional。这意味着self.window?.visible会返回Bool?。而且,当窗口不是nil时它总是存在,它将通过检查。

有关可选链接的Swift小册子部分对此进行了解释。这是有道理的,因为当你使用Optional Chaining时,返回值总是有机会返回nil,而这并不依赖于“链”中的最终值。

注意:以上情况仍属实,但以下建议很糟糕:[

所以你想要的语法是:

(self.window?.visible)!

以下是一些代码,您可以将其粘贴到Playground中以使用此行为:

import Foundation
class a {
    let t = true;
    let f = false;
}

class b {
    var A:a?
}

let B = b()
B.A = a()

if B.A?.f == true {
    println("true")
}
else {
    println("false") // prints False
}