類型在swift中有兩種鸦列,第一種,是
value type
鹏倘,每個實例持有對自己的數(shù)據(jù)獨一無二的副本薯嗤。一般用來定義struct
,enum
,tuple
.第二種,reference type
實例共享一個副本數(shù)據(jù)纤泵,一般用來定義class
骆姐。這這篇文章中我們來探索一下值value type
和reference type
各自的優(yōu)缺點。在使用的時候如何做出選擇捏题。
他們的區(qū)別在哪里
對于value type
來講玻褪,最大的不同點是copy,這影響公荧,賦值带射、初始化、參數(shù)的傳遞循狰。value type
創(chuàng)建了一無依賴實例來持有數(shù)據(jù)唯一的副本窟社。
//Value type example
struct S { var data: Int = -1 }
var a = S()
var b = a //a is copied to b
a.data = 42 // Changes a, not b
println("\(a.data),\(b.data)") //prints "42, -1"
拷貝引用捻浦,換句話講,就是偷偷的創(chuàng)建了一個共享類型的實例桥爽。在拷貝之后,兩個變量其實是指向同一個內容昧识,所以修改第二個變量也會影響第一個钠四。eg:
//Reference type example
class C { var data: Int = -1 }
var x = C()
var y = x //x is copied to y
x.data = 42 //changes the instance referred to by x (and y)
println("\(x.data), \(y.data)") //prints "42, 42"
在安全領域這兩中角色的體現(xiàn)
其中一個選擇value type
而不是reference type
的原因就是使用value type
可以更加簡潔明了的解釋你的代碼。如果你這樣做了--使用value type
跪楞,你在修改你的變量的時候缀去,可以絕對的相信,沒有其他的部分會正在修改你的變量甸祭。在一個多線程操作的環(huán)境下這是特別有用的缕碎,不同的線程都可以修改你的數(shù)據(jù),這會引起一些讓你不愉快的bug池户,并且它們是非常難以調試咏雌。
上面的區(qū)別是數(shù)據(jù)發(fā)生改變的時候產生的。有一種情況校焦,value type
和reference type
重疊:當實例沒有可寫的數(shù)據(jù)(沒有進行赊抖,賦值,傳參等)寨典,變化沒有發(fā)生時氛雪,value type
和reference type
的行為是相同的。
意思是耸成,在沒有發(fā)生賦值操作的時候报亩,
value type
和reference type
沒有什么區(qū)別。
重疊:reference type
可以通過let
屬性修飾符井氢,讓它達到和value type
某種程度上的相似
你也應該發(fā)現(xiàn)這是非常重要弦追。不可變class
就是一個例子。在維護一個語意值上的優(yōu)勢的時候毙沾,這讓使用Cocoa NSObject
對象更加的簡單骗卜。今天在Swift中,我們可以寫一個不可變的class
左胞,通過使用一個不可變的stored propertyies
寇仓,避免暴露的api可以修改任何數(shù)據(jù)狀態(tài)。事實上烤宙,許多普通的Cocoa類遍烦,例如 NSURL
,被設計作為一種不可變的類躺枕。但是Swift目前沒有提供任何語言上的機制來強制class
b永遠不能改變(在子類中可以把父類的let
屬性服猪,重寫)供填。除了value type
,struct
和enum
不可變。
如何做出選擇
那么如果你想要初始化一個類型罢猪,你如何選擇呢近她。當我們和Cocoa打交道的時候,許多API理所當然都是NSObject
的子類膳帕,所以你必須使用class
粘捎。對于這些情況,這里有一些指導:
使用value type
- 用==比較兩個實例才有意義的時候
- 你想要通過copy達到一種沒有依賴的狀態(tài)
- 數(shù)據(jù)將會被使用在多個線程中
使用reference type
- 用===比較兩個實例才有意義的時候
- 你想要你的數(shù)據(jù)模型達到一種共享的可變化的狀態(tài)
在Swift中危彩,Array
攒磨、String
、Dictionary
都是值類型汤徽。它們的行為就像C中的int
娩缰,擁有唯一的數(shù)據(jù)實例。你不需要做任何特殊的操作谒府,例如拼坎,做一個明確的拷貝,來防止其他的代碼在你沒注意的時候修改你的實例完疫。最重要的是演痒,你可以在非同步的情況下,很安全的傳遞你的數(shù)據(jù)趋惨。本著提高安全性的目的鸟顺,在Swift中,這種模型將會幫助你寫出更加可預測的代碼器虾。