UIApplicationDelegate 协议的属性window 声明如下:
optional var window: UIWindow? { get set }
这意味着它是一个可选属性(在某种意义上,“实现UIApplicationDelegate 协议的类不需要实现/拥有这个属性”,就像你在 Objective-C 中有 @optional 时一样),并且该属性是可选类型 Optional<UIWindow>(或UIWindow?)。
这就是为什么最后会有双可选类型,因为window 属性可能会或可能不会在 realDelegate 中实现,如果是,它本身就是Optional<UIWindow>/UIWindow? 类型。
所以基本上你想要的是返回你的realAppDelegate 的window 属性......只有当realAppDelegate 决定声明该属性本身时(它不需要这样做,因为它是optional var) .
- 如果
realAppDelegate 本身没有实现window,您可能打算因此返回nil UIWindow?。
- 如果您的
realAppDelegate 确实实现了 window 属性,那么您需要按原样返回它(无论此实现返回实际的 UIWindow 还是 nil 之一)。
最简单的方法是在 Swift 中使用 nil-coalescing 运算符??。 a ?? b 表示“如果 a 非 nil,则返回 a,但如果 a 为 nil,则返回 b”(如果 a 的类型为 T?,则整个表达式应返回输入T,在你的例子中T 是UIWindow?)。
var window: UIWindow? {
get {
// If realAppDelegate.window (of type UIWindow??) is not implemented
// then return nil. Otherwise, return its value (of type UIWindow?)
return realAppDelegate.window ?? nil
// That code is equivalent (but more concise) to this kind of code:
// if let w = realAppDelegate.window { return w } else return nil
}
...
}
要实现setter,这是另一个问题。根据this SO answer,直接访问协议的可选属性的设置器似乎是不可能的。但是你可以想象一个解决这个问题的方法,通过声明另一个协议,使这个 window 属性要求是强制性的,然后尝试在 setter 中强制转换它:
@objc protocol UIApplicationDelegateWithWindow : UIApplicationDelegate {
var window: UIWindow? { get set }
}
class AppDelegateWrapper : UIApplicationDelegate {
...
var window: UIWindow? {
get {
return realAppDelegate.window ?? nil
}
set {
if let realAppDelWithWindow = realAppDelegate as? UIApplicationDelegateWithWindow
{
// Cast succeeded, so the 'window' property exists and is now accessible
realAppDelWithWindow.window = newValue
}
}
}
...
}