Swift可选可选
对于我的项目,我必须创建一个代理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??
。
有人知道为什么吗?
UIApplicationDelegate
协议的属性window
声明如下:
optional var window: UIWindow? { get set }
这意味着它是一个可选属性 (在某种意义上说“实现UIApplicationDelegate
协议的类不被要求实现/具有此属性 ”,就像在Objective-C中有@optional
那样),并且该属性是可选类型 Optional
(或UIWindow?
)。
这就是为什么你最后有双重可选类型的原因,因为那个window
属性可能会或者可能不会在realDelegate中实现,如果是,它本身就是Optional
/ UIWindow?
。
所以基本上你想要的是返回你的realAppDelegate
的window
属性…只有当realAppDelegate
决定声明该属性本身时(它不需要这样做,因为它是optional var
)。
- 如果
realAppDelegate
没有实现window
本身,你可能打算返回一个nil
UIWindow?
结果是。 - 如果你的
realAppDelegate
确实实现了window
属性,那么你需要按原样返回它(这个实现返回一个实际的UIWindow
或者一个nil
)。
最简单的方法是使用nil-coalescing运算符??
在斯威夫特。 a ?? b
a ?? b
表示“如果a是非nil,则返回a,但如果a为nil,则返回b”(如果a
是T?
类型,则整个表达式应返回T
类型的对象,其中in你的情况T
是UIWindow?
类型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,这是另一个问题。 根据这个SO答案 ,直接访问协议的可选属性的setter似乎是不可能的。 但你可以想象一个黑客来解决这个问题,通过声明另一个使这个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 } } } ... }
财产的声明是
optional var window: UIWindow? { get set }
开头的optional
意味着该属性根本不必存在,那是第二个?
。
UIApplicationDelegate
是一个协议,实现它的类不必实现所有内容。