簡體   English   中英

Swift Lazy和Optional屬性

[英]Swift Lazy and Optional properties

Swift中的LazyOptional屬性有什么區別?

例如,如果有人正在構建從側面進來的導航欄,我認為應該都在一個UIViewController 用戶可能永遠不會打開菜單,但有時他們會打開。

var menu: NavigationBar?
lazy var menu: NavigationBar = NavigationBar.initialize()

我認為這兩個選項都是很好的代碼,因為除非需要,否則它們不會創建視圖。 我理解Optional意味着可能有一個值可能是nil 我也理解Lazy意味着在我需要它之前不要擔心它。

具體問題

我的問題是他們的表現模式(安全性和速度)表明選項更快更安全或反之亦然?

好的,這是一個有趣的問題,我不想暗示現有的答案並不好,但我想我會提出我的看法。

lazy變量非常適合需要設置一次的東西,然后永遠不會重新設置。 它是一個變量,因此您可以將其更改為其他內容,但這種方法會破壞lazy變量的目的(即根據需要設置自己)。

對於可能消失的東西(可能會再次出現),可選項更多。 每次都需要設置它們。

因此,讓我們看一下側邊菜單的兩種情況:一種是在不可見的情況下留在周圍的情況,另一種是在取消分配時。

lazy var sideMenu = SideMenu()

因此,第一次訪問sideMenu屬性時,將調用SideMenu()並將其分配給屬性。 即使你沒有使用它,實例也會永遠存在。

現在讓我們看看另一種方法。

var _sideMenu: SideMenu?
var sideMenu: SideMenu! {
    get {
        if let sm = _sideMenu {
            return sm
        } else {
            let sm = SideMenu()
            _sideMenu = sm
            return sm
        }
    }
    set(newValue) {
        _sideMenu = newValue
    }
}

(注意這只適用於類,而不適用於結構。)

好的,這是做什么的? 它的行為與lazy var非常相似,但它讓你重新設置為nil 因此,如果您嘗試訪問sideMenu ,則可以保證獲得一個實例(存儲在_sideMenu中的_sideMenu或新實例)。 這是一個類似的模式,它懶惰地加載SideMenu()但是這個可以創建許多SideMenu()實例,前面的例子只能創建一次。

現在,大多數視圖控制器都足夠小,你應該只使用之前的lazy

因此,針對同一問題的兩種不同方法。 兩者都有利有弊,在不同情況下工作更好或更差。

他們實際上是非常不同的。

Optional意味着該值可能為零,並且用戶不保證它不會。 在您的示例中, var menu: NavigationBar? 除非有明確指定的內容,否則在整個課程的生命周期內都可能為零。

另一方面, Lazy意味着在第一次訪問賦值時不會調用賦值,這意味着代碼中的某個地方有人試圖使用您的對象。 但是請注意,如果你聲明它就像你在這里lazy var menu: NavigationBar = NavigationBar.initialize()那樣STILL承諾不是nil lazy var menu: NavigationBar = NavigationBar.initialize() ,所以不需要做可選的鏈接。

實際上,變量可以是BOTH Lazy AND Optional ,這意味着它的值將在首次訪問時加載,並且該值在初始化時或任何未來點可能為nil。 例如:

lazy var menu: NavigationBar? = NavigationBar.initialize()

現在允許NavigationBar.initialize()返回nil,或者將來的某個人可以將menu設置為nil,而不會導致編譯器/運行時拋出錯誤!

這有什么區別嗎?

編輯:至於哪個更好,這是一個案例的事情。 Lazy變量在第一次初始化時會受到性能影響,因此如果初始化過程很長,第一次訪問將會很慢。 否則,它們在安全性/性能方面幾乎相同。 在使用之前你需要打開的Optional變量,因此它的性能成本很低(一台機器指令,不值得花時間考慮)

可選和惰性屬性不一樣

  • 當有可能值不可用時(即可以為nil),使用可選屬性。 但在您的方案中,導航欄將始終可用,只是用戶可能無法打開它。
  • 因此,使用懶惰的房產符合您的目的。 只有當用戶點擊它時,才會初始化NavigationBar。

我沒有看到任何性能問題,除非你使用一個可選項,在訪問它之前每次檢查值是否為nil還有額外的開銷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM