繁体   English   中英

Swift可选可选

[英]Swift Optional of 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.window是一个UIWindow??

有人知道为什么吗?

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

optional var window: UIWindow? { get set }

这意味着它是一个可选属性 (在某种意义上说“实现UIApplicationDelegate协议的类不被要求实现/具有此属性 ”,就像在Objective-C中有@optional那样),并且该属性是可选类型 Optional<UIWindow> (或UIWindow? )。

这就是为什么你最后有双重可选类型的原因,因为那个window属性可能会或者可能不会在realDelegate中实现,如果是,它本身就是Optional<UIWindow> / UIWindow?


所以基本上你想要的是返回你的realAppDelegatewindow属性......只有当realAppDelegate决定声明该属性本身时(它不需要这样做,因为它是optional var )。

  • 如果realAppDelegate没有实现window本身,你可能打算返回一个nil UIWindow? 结果是。
  • 如果你的realAppDelegate确实实现了window属性,那么你需要按原样返回它(这个实现返回一个实际的UIWindow或者一个nil )。

最简单的方法是使用nil-coalescing运算符?? 在斯威夫特。 a ?? b a ?? b表示“如果a是非nil,则返回a,但如果a为nil,则返回b”(如果aT?类型,则整个表达式应返回T类型的对象,其中in你的情况TUIWindow?类型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是一个协议,实现它的类不必实现所有内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM