Swift Optionals - 不一致?

时间:2014-07-09 10:35:55

标签: ios swift

我有点困惑 - 我认为我理解了Optionals并且在Apple开发论坛Chris L上,提到了一个解决不可变的可选问题的方法是为可选的值类型创建一个类包装器。 ! - link

但是,请使用UIWindow(具有各种属性的可选类类型)

使用可选链接,属性似乎仍然不可变!

var window: UIWindow?

//this works (force unwrap)
self.window!.backgroundColor = UIColor.greenColor()


//this optional chain doesn't work... why not? Isn't this just a safer version of the above?
self.window?.backgroundColor = UIColor.redColor()

这似乎在测试版5中得到修复!

2 个答案:

答案 0 :(得分:5)

可选链接用于读取值(返回值或nil),它适用于调用方法(调用此方法或不执行任何操作)但不适用于分配。

我相信这是设计的,但我不明白为什么会这样,因为这基本上与以下相同:

extension UIWindow {
    func setBackgroundColor(color: UIColor) {
        self.backgroundColor = color
    }
}

self.window?.setBackgroundColor(UIColor.redColor())

这没有问题。您可以在开发论坛上报告错误或询问。 我认为这里的可选链接在逻辑上是不一致的。

来自dev论坛的示例与此问题没有任何关系,因为该问题与值类型有关。

答案 1 :(得分:5)

更新Xcode beta 5


最初询问的问题已在Xcode beta5中得到解决,这可能会使此答案无效。


原始的anwer


可能会要求进一步解释,为什么它肯定是不一致的行为,但很简单无效。

可选的必须始终是实际操作数的 right 侧,并且它不能位于 left

通过两个简单的例子来看这个逻辑:

示例1

如果是这行代码:

self.window?.backgroundColor = UIColor.redColor()
                      < LEFT ^ RIGHT >

可选是在左侧侧,这意味着左侧侧可能是nil,因此以下操作数将在运行时出现:

nil = UIColor.redColor()

在每个级别上显然都是无效的,没有任何进一步或复杂的解释 - nil不能分配给其他东西,这就是编译器不允许的原因。

  

注意:您可能会认为self.window = nil的情况下逻辑行为是这样的:

nil.backgroundColor = UIColor.redColor()
     

但是关于Optional Chaining的文档强调了一个非常重要的行为,这解释了为什么根本不会发生这种行为:

     
    

多个查询可以链接在一起,如果链中的任何链接为nil,则整个链会正常失败。

  

重点是“整个”这个词,因此方面将是nil = ... { {1}}正如您在 Objective-C 之后所期望的那样。

示例2

另一个答案是关于如何解决它的另一个想法:

nil.backgroundColor = ...

为什么这样有效?这不是一点点不一致吗?绝对没有。

实际的可选项位于操作数的右侧侧,因为该行等于此行,但我们并不打算在实践中获得self.window?.setBackgroundColor(UIColor.redColor())

void

如你所见,这里没有任何不一致,因为在let result: Void! = self.window?.setBackgroundColor(UIColor.redColor()) < LEFT ^ RIGHT > 的情况下,该行在运行时 中等于这一行(请参阅上面的解释)

self.window = nil

这将是一个完全合法的操作数。

逻辑很简单,可选项必须始终位于操作数(或运算符)的 right 侧, left 侧可以是非可选的<只有em> value 。