swift中類型主要分兩類揽惹,分別是值類型和引用類型秋忙。這兩種類型的功能類似于OC中的深拷貝和淺拷貝盔沫。
類型定義 | 定義類型 | |
---|---|---|
值類型 | 每個(gè)實(shí)例保留其數(shù)據(jù)的唯一副本 | struct医咨、enum和tuple |
引用類型 | 實(shí)例共享數(shù)據(jù)的單個(gè)副本 | class |
值類型
值類型通常被定義為 struct、enum和tuple架诞。他的主要特點(diǎn)是拟淮,每個(gè)實(shí)例都保留其數(shù)據(jù)的唯一副本,通俗點(diǎn)說修改 A 實(shí)例中的值不會(huì)影響到 B 實(shí)例谴忧。如下所示
struct S {
var data = 1
}
func valueTypeMethod() {
var a = S()
let b = a
print("\(a.data),\(b.data)") // 1,1
a.data = 2 //改變a中的值
print("\(a.data),\(b.data)") // 2,1
}
引用類型
引用類型通常被定義為 class很泊。他主要的特點(diǎn)是,實(shí)例共享數(shù)據(jù)的單個(gè)副本俏蛮,通俗點(diǎn)說修改 A 實(shí)例中的值會(huì)影響到 B 實(shí)例撑蚌。如下所示:
class C {
var data = 1
}
func referenceTypeMethod() {
var a = C()
let b = a
print("\(a.data),\(b.data)") // 1,1
a.data = 2 //改變a中的值
print("\(a.data),\(b.data)") // 2,2
}
為什么會(huì)存在這兩種類型
swift 為什么會(huì)同時(shí)存在引用類型和值類型,引用類型是不是能滿足一切搏屑,那為什么還有值類型呢争涌?
想想如果在多線程環(huán)境中使用引用類型,此時(shí)我們始終獲得一個(gè)唯一的實(shí)例辣恋,但是不同的線程可能會(huì)同時(shí)對(duì)實(shí)例進(jìn)行亮垫,這時(shí)可能會(huì)產(chǎn)生難以預(yù)料的錯(cuò)誤模软,而這種錯(cuò)誤很難進(jìn)行調(diào)試分析。如果是值類型饮潦,我們可以通過分析不同的實(shí)例燃异,來幫我們輕松的查找和推理代碼中出現(xiàn)的問題。
還有一種情況是當(dāng)實(shí)例中沒有數(shù)據(jù)可進(jìn)行更改時(shí)继蜡,值類型和引用類型的行為是完全相同的回俐。如果某個(gè)類完全不可變,可能會(huì)更有價(jià)值稀并,swift 中要實(shí)現(xiàn)這樣的類可以通過結(jié)合不可變的屬性和避免公開狀態(tài)的API來實(shí)現(xiàn)仅颇。而它目前沒有提供任何語言機(jī)制來實(shí)現(xiàn)對(duì)結(jié)構(gòu)和枚舉的不可變性。OC 中許多累被設(shè)計(jì)成不可變例如 NSURL碘举。
兩種類型如何選擇忘瓦?
在 OC 中,許多 API 都是 NSObject 的子類引颈,當(dāng)我們?cè)趕wift中新建一個(gè)類型時(shí)耕皮,如何去選擇?
選擇值類型
- 實(shí)例數(shù)據(jù)間進(jìn)行 == 比較有意義
- 副本具有獨(dú)立的狀態(tài)
- 數(shù)據(jù)將在多個(gè)線程中使用
選擇引用類型
- 實(shí)例之間進(jìn)行 === 比較有意義
- 實(shí)例內(nèi)數(shù)據(jù)的變化需要共享
以上內(nèi)容參考以下文章