我有点困惑 - 我认为我理解了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中得到修复!
答案 0 :(得分:5)
可选链接用于读取值(返回值或nil
),它适用于调用方法(调用此方法或不执行任何操作)但不适用于分配。
我相信这是设计的,但我不明白为什么会这样,因为这基本上与以下相同:
extension UIWindow {
func setBackgroundColor(color: UIColor) {
self.backgroundColor = color
}
}
self.window?.setBackgroundColor(UIColor.redColor())
这没有问题。您可以在开发论坛上报告错误或询问。 我认为这里的可选链接在逻辑上是不一致的。
来自dev论坛的示例与此问题没有任何关系,因为该问题与值类型有关。
答案 1 :(得分:5)
最初询问的问题已在Xcode beta5中得到解决,这可能会使此答案无效。
可能会要求进一步解释,为什么它肯定是不一致的行为,但很简单无效。
通过两个简单的例子来看这个逻辑:
如果是这行代码:
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 之后所期望的那样。
另一个答案是关于如何解决它的另一个想法:
nil.backgroundColor = ...
为什么这样有效?这不是一点点不一致吗?绝对没有。
实际的可选项位于操作数的右侧侧,因为该行等于此行,但我们并不打算在实践中获得self.window?.setBackgroundColor(UIColor.redColor())
。
void
如你所见,这里没有任何不一致,因为在let result: Void! = self.window?.setBackgroundColor(UIColor.redColor())
< LEFT ^ RIGHT >
的情况下,该行在运行时 中等于这一行(请参阅上面的解释) :
self.window = nil
这将是一个完全合法的操作数。