簡體   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