一尘不染

为什么double类型的主窗口是可选的?

swift

访问UIapplication's主窗口时,它将作为UIWindow??

let view = UIApplication.sharedApplication().delegate?.window // view:UIWindow??

为什么它返回为double可选,这是什么意思?如果放入a中if let,我应该!在其后添加一个?

if let view = UIApplication.sharedApplication().delegate?.window!

尽管我的第一个建议是替换?!after委托,但这不是解决方案。


阅读 185

收藏
2020-07-07

共1个答案

一尘不染

@matt有详细信息,但是有一个(有点可怕,有点很棒)的解决方法。(不过请参见下面的编辑)

let window = app.delegate?.window??.`self`()

我会将对这一行代码的理解留给读者作为练习。

好吧,我撒谎,让我们分解一下。

app.delegate?.window

好的,到目前为止很好。在这一点上,我们感到UIWindow??头痛(我相信这是Swift和Cocoa之间的Swift断开连接中的 错误
)。我们要折叠两次。我们可以使用可选的链接(?.)来做到这一点,但是可以解包和重新包装,因此我们回到了起点。您可以使用double-optional-
chain,虽然??.很奇怪,但是可以使用。

很好,但??不是合法的后缀运算符。您实际上必须链接到某个东西。好吧,我们想重新链接到自身(即“身份”)。该NSObject协议为我们提供了一种身份验证方法:self

self是上的方法NSObject,但在Swift中也是保留字,因此其语法为`self()`

这样我们就可以疯狂起来。随便使用它。

请注意,既然??.可以使用,从技术上讲您就不需要此。你可以接受viewUIWindow??,并使用??.它像view??.frame。这有点嘈杂,但可能不会在需要的几个地方造成任何实际问题。

(*)我曾经将其视为Swift中的错误,但无法通过可选链直接修复。问题是没有可选的链接过去window。因此,我不确定在哪里进行修复。Swift可以?在不需要链接的情况下允许postfix-
表示“扁平化”,但这听起来很奇怪。我猜正确的运算符应该是interrobang delegate?.window‽:D我敢肯定这不会引起任何混乱。

编辑:

约瑟夫·洛德Joseph
Lord)指出了更好的解决方案
(与我一直在使用的避免琐碎if-
let的技术非常相似,但之前从未想到过这种方法):

let window = app.delegate?.window ?? nil // UIWindow?

我同意他的看法,这是正确的答案。

2020-07-07