在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ iOS/ Swift 里的值類型與引用類型
特性(Attributes)
Access Control 權(quán)限控制的黑與白
基本運(yùn)算符(Basic Operators)
基礎(chǔ)部分(The Basics)
閉包(Closures)
擴(kuò)展
泛型參數(shù)(Generic Parameters and Arguments)
訪問控制和 protected
語句(Statements)
模式(Patterns)
WWDC 里面的那個(gè)“大炮打氣球”
關(guān)于語言參考(About the Language Reference)
語法總結(jié)(Summary of the Grammar)
嵌套類型
類型(Types)
Swift 初見(A Swift Tour)
泛型
枚舉(Enumerations)
高級運(yùn)算符
繼承
析構(gòu)過程
關(guān)于 Swift(About Swift)
訪問控制
類和結(jié)構(gòu)體
內(nèi)存安全
Swift 與 C 語言指針友好合作
協(xié)議
屬性(Properties)
可選類型完美解決占位問題
錯(cuò)誤處理
字符串和字符(Strings and Characters)
聲明(Declarations)
自動(dòng)引用計(jì)數(shù)
Swift 里的值類型與引用類型
表達(dá)式(Expressions)
Swift 文檔修訂歷史
造個(gè)類型不是夢-白話 Swift 類型創(chuàng)建
歡迎使用 Swift
詞法結(jié)構(gòu)(Lexical Structure)
集合類型(Collection Types)
下標(biāo)
方法(Methods)
可選鏈?zhǔn)秸{(diào)用
版本兼容性
類型轉(zhuǎn)換
構(gòu)造過程
The Swift Programming Language 中文版
函數(shù)(Functions)
Swift 教程
控制流(Control Flow)

Swift 里的值類型與引用類型


翻譯:老碼團(tuán)隊(duì)翻譯組-Arya 校對:老碼團(tuán)隊(duì)翻譯組-Jame

本頁包含內(nèi)容:

Swift 里面的類型分為兩種:

  • 值類型(Value Types):每個(gè)實(shí)例都保留了一分獨(dú)有的數(shù)據(jù)拷貝,一般以結(jié)構(gòu)體 (struct)、枚舉(enum) 或者 元組(tuple)的形式出現(xiàn)。
  • 引用類型(Reference Type):每個(gè)實(shí)例共享同一份數(shù)據(jù)來源,一般以 類(class)的形式出現(xiàn)。

在這篇博文里面,我們會介紹兩種類型各自的優(yōu)點(diǎn),以及應(yīng)該怎么選擇使用。

值類型與引用類型的區(qū)別

值類型和引用類型最基本的分別在復(fù)制之后的結(jié)果。當(dāng)一個(gè)值類型被復(fù)制的時(shí)候,相當(dāng)于創(chuàng)造了一個(gè)完全獨(dú)立的實(shí)例,這個(gè)實(shí)例保有屬于自己的獨(dú)有數(shù)據(jù),數(shù)據(jù)不會受到其他實(shí)例的數(shù)據(jù)變化影響:

    // 下面是一個(gè)值類型的例子
    struct S { var data: Int = -1 }
    var a = S()
    var b = a                           // b 是 a 的拷貝
    a.data = 42                         // 更改 a 的數(shù)據(jù),b 的不受影響
    println("\(a.data), \(b.data)")     // 輸出結(jié)果 "42, -1"

值類型就好像身份證復(fù)印件一樣,復(fù)印出來之后,修改原件上面的內(nèi)容,復(fù)印件上的內(nèi)容不會變。

另一方面,復(fù)制一個(gè)引用類型的時(shí)候,實(shí)際上是默默地創(chuàng)造了一個(gè)共享的實(shí)例分身,兩者是共用一套數(shù)據(jù)。因此修改其中任何一個(gè)實(shí)例的數(shù)據(jù),也會影響到另外那個(gè)。

    // 下面是一個(gè)引用類型的例子
    class C { var data: Int = -1 }
    var x = C()
    var y = x                           // y 是 x 的拷貝
    x.data = 42                         // 更改 x 的數(shù)據(jù),等于同時(shí)修改了 y
    println("\(x.data), \(y.data)")     // 輸出結(jié)果 "42, 42"

Mutation(修改)在安全中扮演的角色

值類型較引用類型來說,會讓你更容易在大量代碼中理清狀況。如果你總是得到一個(gè)獨(dú)立的拷貝出來的實(shí)例,你就可以放心它不會被你 app 里面的其他部分代碼默默地修改。這在多線程的環(huán)境里面是尤為重要的,因?yàn)榱硗庖粋€(gè)線程可能會在暗地里修改你的數(shù)據(jù)。因此可能會造成嚴(yán)重的程序錯(cuò)誤,這在調(diào)試過程中非常難以排除。

由于差別主要在于修改數(shù)據(jù)的后果,那么當(dāng)實(shí)例的數(shù)據(jù)只讀,不存在需要更改的情況下,用哪種類型都是沒有分別的。

你可能在想,有的時(shí)候我可能也需要一個(gè)完全不變的類。這樣使用 Cocoa NSObject 對象的時(shí)候會比較容易,又可以保留值語義的好處。在今天,你可以通過只使用不可變的存儲屬性,和避開任何可以修改狀態(tài)的 API,用 Swift 寫出一個(gè)不可變類 (immutable class)。實(shí)際上,很多基本的 Cocoa 類,例如 NSURL,都是設(shè)計(jì)成不可變類的。然而,Swift 語言目前只強(qiáng)制 structenum 這種值類型的不可變性,對類這種引用類型則沒有。(例如還不支持強(qiáng)制將子類的限制為不可變類)

如何選擇類型?

所以當(dāng)我們想要建立一個(gè)新的類型的時(shí)候,怎么決定用值類型還是引用類型呢?當(dāng)你使用 Cocoa 框架的時(shí)候,很多 API 都要通過 NSObject 的子類使用,所以這時(shí)候必須要用到引用類型 class。在其他情況下,有下面幾個(gè)準(zhǔn)則:

  • 什么時(shí)候該用值類型

    • 要用==運(yùn)算符來比較實(shí)例的數(shù)據(jù)時(shí)
    • 你希望那個(gè)實(shí)例的拷貝能保持獨(dú)立的狀態(tài)時(shí)
    • 數(shù)據(jù)會被多個(gè)線程使用時(shí)
  • 什么時(shí)候該用引用類型(class)
    • 要用==運(yùn)算符來比較實(shí)例身份的時(shí)候
    • 你希望有創(chuàng)建一個(gè)共享的、可變對象的時(shí)候

在 Swift 里面,數(shù)組(Array)、字符串(String)、字典(Dictionary)都屬于值類型。它們就像 C 語言里面簡單的 int 值,是一個(gè)個(gè)獨(dú)立的數(shù)據(jù)個(gè)體。你不需要花任何功夫來防范其他代碼在暗地里修改它們。更重要的是,你可以在線程之間安全的傳遞變量,而不需要特地去同步。在 Swift 高安全性的精神下,這個(gè)模式會幫助你用 Swift 寫出更可控的代碼。


本章節(jié)不是老碼的原創(chuàng),老碼認(rèn)真的閱讀了蘋果的官方博客,且自己的練習(xí)總結(jié),如果小伙伴們費(fèi)了吃奶的勁還是看不懂,請找度娘谷歌,還是看不懂請到老碼官方微博咆哮。

本文由翻譯自 Apple Swift Blog :Value and Reference Types