【iOS 印象】Swift 中值類型與引用類型指北


值類型(Value)與引用類型(Reference)

Swift 中結構體(struct)可定義屬性與方法,能夠指定初始化方法,實現協議,除了繼承,類(class)能作的,結構體幾乎都能作,那麼何時用結構體,何時用類就成了個問題,換句話說,就是在 Swift 中,什麼狀況應該用值類型,什麼狀況下用引用類型?

  • 值類型:結構體(Struct)、枚舉(Enum)、元組(Tuple)
  • 引用類型:類(Class)、函數(Function)

語義

  • 值類型:變量與其所賦值分配的數據(值)邏輯統一,通常將其視爲儲存在棧(Stack)上,但實際上,一部分數據在 CPU 寄存器,其它一部分仍是分配在堆(Heap)上。能夠感性地將其理解爲,值類型的數據(值)被包含在了變量中,不可以單獨被操做。
  • 引用類型:與值類型正好相反,變量與其分配的數據(實例)是分離的,引用類型的實例分配在堆(Heap)上,變量分配在棧上,僅持有該實例在內存中的地址,能夠有多個變量指向同一個實例,該實例可獨立地被其中任意指向它的變量操做。

// 值類型
struct CatStruct {
    var name: String
}

let a = CatStruct(name: "Whiskers")
var b = a
b.name = "Fluffy"

print(a.name)   // Whiskers
print(b.name)   // Fluffy

// 引用類型
class CatClass {
    init(name: String) {
        self.name = name
    }
    
    var name: String
}

let x = CatClass(name: "Whiskers")
let y = x
y.name = "Fluffy"

print(x.name)   // Fluffy
print(y.name)   // Fluffy複製代碼

可變性(Mutability)概念的不一樣

  • 區分變量(variable)可變性與實例(instance)可變性
  • 因爲值類型,變量與實例在邏輯上是統一體,所以值類型的變量可變性,即其實例的可變性
  • 引用類型,變量與其所指向的實例是分離的,所以變量的可變性,僅僅表明其始終指向同一實例,不表明其實例的可變性,其實例中的具體數據(屬性)等仍保持其自身的可變性。

值類型的特性

  • ​基於屬性的可等性(Attribute-based equality)
  • 沒有身份標識與生命週期(Lack of Identity or lifecycle)
  • 可替代性(Substitutability)
  • 以上三個特性總結下來就是:5 美圓就是 5 美圓,到哪兒都是 5 美圓

值類型的優勢

  • ​高效:引用類型在堆上分配,相比棧上分配開支更大。Swift 中,值類型基於其特性實現了 copy on write,即當可變值類型真正發生改變那一刻時纔會爲其分配內存空間。
  • 無反作用(可預測):不一樣於引用類型的實例可被多個變量引用並操做,值類型的特性能夠有效避免代碼的反作用。
  • 線程安全
  • 沒有內存泄露的問題
  • 易測試

值類型與引用類型在應用開發中如何設計使用

  1. ​引用類型用於構建有身份標識(identity)的模型實體(model entity)
    • 若該狀況下采用值類型,則易形成同一身份標識的數據(屬性)不一致問題
  2. 值類型用於封裝狀態,暴露行爲,表述業務邏輯
  3. 使用環境很是重要
  4. 基於屬性的可等性的測試
  5. 值類型與引用類型的組合使用
    • ​將對象構造在值的基礎上

總結

Swift 中提供了強大而高效的值類型,讓咱們的一部分代碼可以更高效、無反作用,而且線程安全。在理解了值類型與引用類型的區別的前提下,組合這兩種數據類型,更好更高效地達成應用目標。
相關文章
相關標籤/搜索