Swift可选可选

时间:2015-04-28 13:07:13

标签: ios swift optional

对于我的项目,我必须创建一个代理AppDelegate,它将调用转发到另一个AppDelegate。

UIApplicationDelegate有一个var window: UIWindow?。我的问题是,为什么我不能这样做:

private lazy var realAppDelegate: UIApplicationDelegate = {
    return AppDelegate()
}()

var window: UIWindow? {
    get {
        return realAppDelegate.window
    }
    set {
        realAppDelegate.window = newValue
    }
}

该代码的问题是realAppDelegate.windowUIWindow??

有人知道为什么吗?

2 个答案:

答案 0 :(得分:7)

window协议的属性UIApplicationDelegate声明如下:

optional var window: UIWindow? { get set }

这意味着它是一个可选属性(从某种意义上说,&#34;实现UIApplicationDelegate协议的类未被请求实现/拥有此属性< / strong>&#34;,就像您在Objective-C中有@optional一样,并且该属性属于可选类型 Optional<UIWindow>(或UIWindow?

这就是为什么你最后有双重可选类型的原因,因为window属性可能在realDelegate中实现,也可能没有,如果是,它本身就是{{1}类型1}} / Optional<UIWindow>

所以基本上你想要的是返回你UIWindow?的{​​{1}}属性...只有当window决定声明该属性本身时(它不是必需的)做,因为它是realAppDelegate)。

  • 如果realAppDelegate本身未实现optional var,您可能打算返回realAppDelegate window作为结果。
  • 如果您的nil确实实现了UIWindow?属性,则需要按原样返回(此实现返回实际的realAppDelegatewindow个)

最简单的方法是在Swift中使用nil-coalescing运算符UIWindownil表示&#34;如果a是非零,则返回a,但如果a为nil,则返回b&#34; (如果??的类型为a ?? b,则整个表达式应返回a类型的对象,在您的情况下T?是{{1}类型}})。

T

要实现setter,这是另一个问题。根据{{​​3}},直接访问协议的可选属性的setter似乎是不可能的。但你可以设想通过声明另一个使T属性要求成为强制性的协议来解决这个问题,然后尝试在setter中强制转换它:

UIWindow?

答案 1 :(得分:1)

该财产的声明是

optional var window: UIWindow? { get set }

开头的optional表示该属性根本不存在,即第二个?

UIApplicationDelegate是一个协议,实现它的类不必实现所有内容。