?
# Swift 值類型和引用類型
原文地址:[https://developer.apple.com/swift/blog/?id=10](https://developer.apple.com/swift/blog/?id=10)
Swift中的類型分為兩類:一,值類型(value types),每個值類型的實例都擁有各自唯一的數據,通常它們是結構體,枚舉或元組;二,引用類型(reference types),引用類型的實例共享它們的數據,通常是一個類。在這篇文章中我們將會探索值類型和引用類型的價值,以及如何在它們二者間抉擇。
## 有什么區別?
值類型最基本的特征就是復制在賦值、初始化和傳遞參數過程中的數據,并為這個數據創建一個獨立的實例:
~~~
// 值類型例子
struct S { var data: Int = -1 }
var a = S()
var b = a // 把a復制給b
a.data = 42 // a被改變了, b卻沒有
println("\(a.data), \(b.data)") // prints "42, -1"
~~~
復制一個引用類型的時候,其實是隱式地創建了一個共享的實例。在復制后,兩個實例指向了同一塊數據,所以當修改其中一個實例數據的時候,另一個實例的數據也被修改了,比如:
~~~
// 引用類型的例子
class C { var data: Int = -1 }
var x = C()
var y = x // x被復制給了y
x.data = 42 // x指向的數據被修改了 (同時y也被修改了)
println("\(x.data), \(y.data)") // prints "42, 42"
~~~
## 可變性在安全中的作用
選擇值類型而不是引用類型的一個主要原因是能讓你的代碼變得更加簡單。你在任何情況下用一個值類型,都能夠假設你的其他代碼不會使它改變,這通常在多線程環境中很有用,如果一個線程中使用的數據被另一個線程給意外的修改了,這通常會產生非常嚴重的Bug,且相當難以調試。
由于只有當你需要修改數據時兩者的區別才會得到體現,所以當你的實例不會對數據進行修改的時候,值類型和引用類型看起來是完全相同的。
你也許會想,寫一個完全不可變的類,這或許是有價值的,使用Cocoa的NSObject能簡化這個過程,并且能很好地保持原有的語義。現在,你能通過使用不可變的存儲屬性,以及避免暴露修改數據的接口,從而在Swift里實現一個不可變的類。事實上,大多數的Cocoa類,比如NSURL等,都被設計為不可變的類,然而,Swift當前并沒有提供任何語言機制去強制申明一個類不可改變(比如子類化就能修改一個類的實現),只有結構體和枚舉才是強制不可變的。
## 如何選擇?
所以如果你想要創建一個新的類型,你怎么選擇?當你寫Cocoa程序的時候,大多數APIs都需要從NSObject繼承,你就已經是一個類了(引用類型),針對其他情況,這里有些指導規則:
使用值類型,當...:
* 通過使用==去比較實例的數據
* 你想得到一個實例的獨立副本
* 數據在多線程環境下被修改
使用引用類型(比如使用一個類),當...:
* 通過使用===去判斷兩個實例是否恒等
* 你想要創建一個共享的,可變的對象
在Swift里,Array、String和Dictionary都是值類型,他們的行為和C語言中的int類似,每個實例都有自己的數據,你不需要額外做任何事情,比如做一個顯式的copy,防止其他代碼在你不知情的情況下修改等,更重要的是,你能安全地在線程間傳遞它,而不需要使用同步技術。在提高安全性的精神下,這個模型將幫助你在Swift中寫出更多可預知的代碼。
- 前言
- iOS 自定義頁面的切換動畫與交互動畫 By Swift
- Swift 元組(Tuples)介紹
- Swift 可選值(Optional Values)介紹
- Swift Switch介紹
- Swift 值類型和引用類型
- Swift 柯里化(Currying)
- iOS GCD使用指南
- iOS8 Core Image In Swift:自動改善圖像以及內置濾鏡的使用
- 讓Xcode自動更新Build版本
- Swift 全功能的繪圖板開發
- Swift Nullability and Objective-C
- Swift Core Data 圖片存儲與讀取Demo
- Swift 繪圖板功能完善以及終極優化
- 如何設計一個 iOS 控件?(iOS 控件完全解析)