簡體   English   中英

斯威夫特的懶惰Var

[英]Swift's Lazy Var

閱讀有關Swift的惰性變量后,我有以下問題:

class MainViewController: UIViewController {

      lazy var heavyClass = HeavyClass()

      func buttonPressed () {
         //Use heavyClass here
         self.heavyClass.doStuff()
      }    
}

因此,您可以使用上面的惰性變量來優化代碼,這樣就不會立即分配heavyClass。 因此,在啟動時,這是最佳選擇,因為在啟動時不會分配heavyClass。

但是,這與上面的一樣嗎?

class MainViewController: UIViewController {

      var heavyClass : HeavyClass?

      func buttonPressed () {
         //Use heavyClass here
         self.heavyClass =  HeavyClass()
         self.heavyClass!.doStuff()
      }    
}

在您的示例中,結果在以下方面並不完全相同:

  1. 單一實例化。 每次調用buttonPressed() ,都會實例化一個新的HeavyClass 使用lazy關鍵字時情況並非如此,后者只會在首次訪問時創建實例。 為了匹配惰性語義,您必須在每次訪問之前檢查並設置heavyClass == nil

  2. 可空性。 你必須解開您heavyClass你想用它每一次,或者通過可選的鏈接( heavyClass?.doStuff()或力展開( heavyClass!.doStuff() 您還可以將變量設置回nil ,這在第一個示例中將是編譯器錯誤。

懶變量的真正勝利是當您有多個使用該變量的地方。 我確定您可以在這里找到重復的內容:

func buttonPressed() {
    if self.heavyClass == nil {
        self.heavyClass = HeavyClass()
    }
    self.heavyClass?.doStuff()
}

func aDifferentButtonPressed() {
    if self.heavyClass == nil {
        self.heavyClass = HeavyClass()
    }
    self.heavyClass?.doSomethingElse()
}

使用惰性變量對此進行整理:

func buttonPressed() {
    self.heavyClass.doStuff()
}

func aDifferentButtonPressed() {
    self.heavyClass.doSomethingElse()
}

解決同一個問題的方法有多種,但在這里我將討論其中的幾種。 問題是您只想在需要時才分配內存。 在某些情況下,您可能會使用一種或另一種方式,並且可能會受到您的編碼風格的一定影響。 一方面,假設該類需要一些設置,所以使用惰性可以提供更好的代碼可讀性。 例如:

lazy var heavyClass: HeavyClass = {
    let heavyClass = HeavyClass()
    heavyClass.attribute1 = X
    heavyClass.attribute2 = X
    heavyClass.attribute3 = X
    heavyClass.attributeAndSoOn = X
    return heavyClass
}()

關鍵是,所有標准設置都包含在此處,並且僅在需要時,您仍會獲得內存分配的好處。 您無需添加功能或延長操作例程(例如buttonPressed)。

在另一種情況下,您可以使用可選參數,但這確實增加了該值為nil的可能性。 然后,您必須添加邏輯來處理此問題。

我也看到過一個解開力的模型,但我自己並不親自使用它。 看起來像這樣:

class MainViewController: UIViewController {

  var heavyClass : HeavyClass!

  func buttonPressed () {
     //Use heavyClass here
     heavyClass = {
        let heavyClass = HeavyClass()
        // do your other stuff here
        return heavyClass
     }()
    heavyClass.doStuff()
  }    
}

這都是優先事項。 我會說惰性var也不是線程安全的。 因此,如果您可以使用該對象有多個線程,則一個線程可以訪問部分構造的對象。

希望這可以幫助!

暫無
暫無

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

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