对于我的项目,我必须创建一个代理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.window
是UIWindow??
。
有人知道为什么吗?
答案 0 :(得分:7)
window
协议的属性UIApplicationDelegate
声明如下:
optional var window: UIWindow? { get set }
这意味着它是一个可选属性(从某种意义上说,"实现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?
属性,则需要按原样返回(此实现返回实际的realAppDelegate
或window
个) 最简单的方法是在Swift中使用nil-coalescing运算符UIWindow
。 nil
表示&#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
是一个协议,实现它的类不必实现所有内容。