在swift中,型別分為兩類:第一種是值型別,該型別的每個例項持有資料的副本,並且該副本對於每個例項來說是獨一無二的乙份,比如結構體(struct)、列舉(enum)、元組(tuple)都是值型別。第二種是參照型別,該型別的例項共享資料唯一的乙份副本(在native層面說的話,就是該型別的每個例項都指向記憶體中的同乙個位址),比如類(class)就是參照型別。在這篇文章中,我們將深入**值型別和參照型別的使用價值,以及如何在某種場景下選擇正確的型別。
值型別最基本的特點就是複製,這影響到它的賦值、初始化、傳參等操作。來看看下面的**示例:
// 值型別示例
struct s
var a = s()
var b = a // a複製乙份,並將副本賦值給了b
a.data = 42 // a的資料改變了,但是b的並沒有改變
println("\(a.data), \(b.data)") // prints "42, -1"
參照型別的複製行為其實是隱式的建立了乙個共享的例項,作為原始型別的參照。下面的例子中,兩個變數都會參照唯一的那個共享例項的資料,所當改變這兩個變數中任何乙個的資料,都會同樣作用於原始型別的資料:
// 參照型別示例
class c
var x = c()
var y = x // 將x賦值給y
x.data = 42 // 修改了x的資料,其實是修改了參照資料,那麼y的資料也會改變
println("\(x.data), \(y.data)") // prints "42, 42"
選擇值型別的乙個很重要的原因是可以讓你比較容易的理解和掌控你的**。如果你使用值型別,那麼都是唯一的資料值、型別的副本在和你打交道,你對資料的修改只作用於資料所屬的型別例項,所以你可以不用擔心因為你在某個地方對資料的修改而影響到其他地方的資料。這在多執行緒環境中非常有用,因為在多執行緒下,不同的執行緒有可能會在你不知情的情況下改變資料。發生這種bug後,除錯起來就非常困難。
因為值型別和參照型別的表象區別就在於當你修改型別例項的資料時,它們對原始型別資料的處理方式不同。但是有一種情況,值型別和參照型別的處理方式卻又相似,那就是當型別例項的資料為唯讀的時候。在不存在修改的情況下,值型別和參照型別就沒什麼區別了。
你可能會覺得這一點很有用,假如說乙個class
是完全不能被重定義的,那麼就比較符合使用cocoa的nsobject
物件的一些習慣,並能很好的保持原本的語義。今天,在swift你可以通過定義不可改變的儲存屬性來建立乙個不可重定義的類,這樣可以避免暴露出的api被修改。事實上,許多普通的cocoa框架裡的類,比如nsurl
,都被定義成了不可重定義的類。儘管如此,swift目前還不提供任何機制像結構體(struct)和列舉(enum)一樣去強制使乙個class
成為不可重定義的類(比如像子類)。
如果你想建立乙個新型別,那麼你應該選擇值型別還是參照型別呢?當你使用cocoa框架時,很多api都是nsobject
的子類,那麼你就必須要使用參照型別,也就是class
。在其他情況下,這裡有一些指導建議你可以參考:
使用值型別的情形:
使用參照型別(比如class
)的情形:
在swift中,array
、string
、dictionary
都是值型別。它們的使用方式類似c語言中得int
,每乙個例項都有乙份資料。你不需要進行顯示的複製操作去防止資料在你不知情的情況下被修改。更重要的是,你可以跨執行緒進行傳參而不需要考慮同步的問題,因為傳遞值型別很安全。秉著高安全性的精神,這種型別劃分模式能幫助你在swift中寫出更加有可**性的**。
Swift 中的值型別和引用型別
值型別和引用型別只在之前的面試過程中碰到過,最近學習過程中,在體驗 swift 的物件導向特性的時候,在 struct 和 class 中再次碰到了這個問題,說一說自己的收穫吧。值型別和引用型別在 oc 裡面理解起來應該更方便。在 oc 中,我們例項化物件的時候有兩種方式。一種是需要在變數名前面加個...
Swift值型別和引用型別
的乙份,比如結構體 struct 列舉 enum 元組 tuple 都是值型別。第二種是引用型別,該型別的例項共享資料唯一的乙份副本 在native層面說的話,就是該型別的每個例項都指向記憶體中的同乙個位址 比如類 class 就是引用型別。在這篇文章中,我們將深入 值型別和引用型別的使用價值,以及...
Swift 值型別和引用型別
swift中有兩種型別 值型別 value type 引用型別 reference type 在swift中,所有的基本型別 整型 int 浮點型 float 布林型別 boolean 字串型別 string 陣列 array 字典 dictionary 元組 tuple 都是值型別,它們的底層都是...