[譯] lazy var in ios swift

kirinzer發表於2019-04-05

在 iOS Swift 中的懶載入變數

這篇文章解釋了在 Swift 中懶載入變數是如何工作的,你必須對閉包有一些瞭解。

閱讀這篇文章獲取更多關於閉包的資訊.

當我們進行 iOS 開發時,我們應該非常關注應用程式的記憶體佔用情況。如果應用程式很複雜,那麼記憶體問題就會是對於開發者的一個主要的挑戰。所以,首先考慮到記憶體分配問題的開發者能夠真正的寫出優化的程式碼。除非確實有必要,否則開發者要避免做一些耗時的工作。那些複雜的分配記憶體操作會消耗更多的時間,並且對於程式的效能有嚴重的影響。

[譯] lazy var in ios swift

Swift 有內建在語言中的機制,可以即時的計算那些耗時工作。它叫做懶載入變數。這種變數只有在你第一次需要它的時候才被指定的方法建立。如果從沒有使用過該變數。那麼方法就不會執行,所以它可以幫助減少一些處理時間。

蘋果的官方文件寫道:

一個懶載入儲存屬性是種只有在首次使用時,才計算其初始值的屬性。你可以通過在宣告前加 lazy 修飾符來標示一個懶載入儲存屬性。

你必須將一個懶載入屬性宣告為一個變數(通過 var 關鍵字),因為它的初始化值也許不能獲得,直到例項的初始化完成。常量屬性在初始化完成之前一定會有一個值,因此不能用懶載入宣告。

為了解釋這些,我會使用一個很基礎的示例:假設有一個結構體叫做 InterviewCandidate。它有一個可選的布林值,決定候選人正在申請 iOS 或者 Android。iOSResumeDescription 和 androidResumeDescription 被宣告為懶載入屬性。那麼在下面的程式碼中,一個人是 iOS 開發者,懶載入變數 iOSResumeDescription 將會在呼叫列印方法的時候被初始化。沒有被呼叫的 androidResumeDescription 就會是 nil。

//: Playground - noun: 人們用來玩耍的地方
import UIKit


struct InterviewCandidate {
    var isiOS:Bool?
    
    lazy var iOSResumeDescription: String = {
        return "I am an iOS developer"
    }()
    lazy var androidResumeDescription: String = {
        return "I am an android developer"
    }()
}

var person1 = InterviewCandidate()
person1.isiOS = true

if person1.isiOS! {
    print(person1.iOSResumeDescription)
} else {
    print(person1.androidResumeDescription)

}
複製程式碼

這是一個非常基礎的例子。如果我們有一個複雜的類或結構,它包含從迴圈的函式返回結果的計算變數,並且如果我們建立 1000 個這樣的物件,那麼效能和記憶體將會受到影響。

懶載入儲存屬性 vs 儲存屬性

這有一些懶載入屬性相對於儲存屬性的優點。

  1. 只有在讀取懶載入屬性時,才會執行與該屬性關聯的閉包。 因此,如果由於某種原因該屬性未被使用(可能是因為使用者的某些決定),則可以避免不必要的分配和計算。

  2. 你可以使用一個儲存屬性給懶載入屬性賦值。

  3. 注意 你能夠在懶載入的屬性閉包內部使用 self。這不會導致任何迴圈引用。原因在於它立即使用的這個閉包 {}() 被認為是 @noescape。它不會引用捕獲的 self

但是,如果你在 方法 中使用 self。事實上,如果你正在使用的是一個類而不是結構體,你也應該在你的方法內宣告 [unowned self] 那樣你才不會建立一個強引用(檢視下面的程式碼)。

// playground code

import UIKit
import Foundation

class InterviewTest {
	var name: String
	lazy var greeting : String = { returnHello \(self.name)” }()
	// 這裡沒有迴圈引用 ..

	init(name: String) {
		self.name = name
	}
}

let testObj = InterviewTest(name:”abhi”)

testObj.greeting
複製程式碼

你能夠引用這個變數,無論你是否使用了閉包。

lazy var iOSResumeDescription = “I am an iOS developer”
複製程式碼

這樣的語法也可以執行。

注意:記住,懶載入屬性的用途是隻有它們第一次被需要的時候才會被計算,在這之後它們的值就被儲存下來了。所以,如果你第二次使用 iOSResumeDescription,預先儲存的屬性就會返回。

懶載入規則:

  • 你不能對 let 型別使用 lazy

  • 你不能對於 計算屬性 使用它。因為一個計算屬性會在每次我們試圖訪問它的時候去執行在計算程式碼塊中的程式碼並返回相應的值。

  • 你只能對 structclass 的成員使用 lazy

  • 懶載入變數不是原子初始化型別,所以它並不是執行緒安全的。

如果你喜歡閱讀這篇文章,那麼分享和推薦它以便其他人能夠看到??????!

如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章