对于我的项目,我必须创建一个代理AppDelegate,该代理将把调用转发到另一个AppDelegate。
UIApplicationDelegate有一个var window: UIWindow?。我的问题是,为什么我不能这样做:
var window: UIWindow?
private lazy var realAppDelegate: UIApplicationDelegate = { return AppDelegate() }() var window: UIWindow? { get { return realAppDelegate.window } set { realAppDelegate.window = newValue } }
该代码的问题realAppDelegate.window是UIWindow??。
realAppDelegate.window
UIWindow??
有人知道为什么吗?
该物业window的UIApplicationDelegate协议,声明如下:
window
UIApplicationDelegate
optional var window: UIWindow? { get set }
这意味着它是一个 可选属性 (在某种意义上,“ 不需要请求 实现UIApplicationDelegate协议的类 来实现/具有此属性 ”,就像 @optional在Objective-C中一样),并且该属性 是可选类型 Optional<UIWindow>(或UIWindow?) 。
@optional
Optional<UIWindow>
UIWindow?
这就是为什么最后要使用double可选类型的原因,因为该window属性可能会或可能不会在realDelegate中实现,如果是,它将本身为Optional<UIWindow>/ 类型UIWindow?。
因此,基本上,您想要的只是返回…的window属性,realAppDelegate除非realAppDelegate该属性决定声明该属性本身(因为它不需要这样做optional var)。
realAppDelegate
optional var
nil
UIWindow
最简单的方法是??在Swift中使用nil-coalescing运算符。a ??b意思是“如果a为非nil,则返回a,但如果a为nil,则返回b”(其中if a是type T?,则整个表达式应返回type的对象T,在您的情况下T为type UIWindow?)。
??
a ??b
a
T?
T
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 } ... }
要实现安装程序,这是另一个问题。根据这个SO答案,似乎不可能直接访问协议的可选属性的设置器。但是您可以想象有一种破解方法,可以通过声明另一个使该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 } } } ... }