關(guān)于值類型和引用類型的一些小解惑
最近在看Swift文檔, 看到String這里的時(shí)候看到一個(gè)值類型的問題, 以前也一直沒有怎么去深究其中的問題, 當(dāng)看到這個(gè)問題的時(shí)候還真有點(diǎn)蒙, 后來看了其他一些資料, 也算是弄明白了.
首先得弄明白什么是值類型, 什么是引用類型, 在Swift
中的類型分為兩類: 一. 值類型, 每個(gè)值類型的實(shí)例都擁有各自唯一的數(shù)據(jù), 通常是結(jié)構(gòu)體, 枚舉或元祖; 二. 引用類型, 引用類型的實(shí)例共享它們的數(shù)據(jù), 通常是一個(gè)類(類的屬性).
有什么區(qū)別?
值類型最基本的特征就是進(jìn)行值拷貝. 初始化和傳遞參數(shù)過程中的數(shù)據(jù), 并為這個(gè)數(shù)據(jù)創(chuàng)建一個(gè)獨(dú)立的實(shí)例. 在Swift
中String
是值類型, 而在OC
中, 要想達(dá)到這樣的效果, 就要使用copy
來修飾才能達(dá)到.
而復(fù)制一個(gè)引用類型的時(shí)候, 其實(shí)是隱式地創(chuàng)建了一個(gè)共享的實(shí)例. 在復(fù)制后, 兩個(gè)實(shí)例指向了同一塊數(shù)據(jù), 所以當(dāng)修改其中一個(gè)實(shí)例數(shù)據(jù)的時(shí)候, 另一個(gè)實(shí)例的數(shù)據(jù)也被修改了. 在OC
中NSString
, NSArray
, NSDictionry
就是引用類型, 這也就是為什么要在當(dāng)屬性是這些數(shù)據(jù)類型的時(shí)候要用copy修飾了, 就是為了數(shù)據(jù)的安全性, 防止因?yàn)閯e人的修改而改變重要的數(shù)據(jù).
如何選擇
在寫Cocoa
程序的時(shí)候, 大多數(shù)APIs都需要從NSObject繼承, 這就已經(jīng)是一個(gè)類了(引用類型), 使用值類型在一下情況:
- 通過使用==去比較實(shí)例的數(shù)據(jù)(比較的是值)
- 想得到一個(gè)實(shí)例的獨(dú)立副本
- 數(shù)據(jù)在多線程環(huán)境下被修改
使用引用類型:
- 通過使用===去判斷兩個(gè)實(shí)例內(nèi)存地址是否相等
- 想創(chuàng)建一個(gè)共享的, 可變的對(duì)象
在Swift中 Array遵班、String和Dictionary都是值類型屠升,他們的行為和C語言中的int類似,每個(gè)實(shí)例都有自己的數(shù)據(jù)狭郑,你不需要額外做任何事情腹暖,比如做一個(gè)顯式的copy,防止其他代碼在你不知情的情況下修改等翰萨,更重要的是脏答,你能安全地在線程間傳遞它,而不需要使用同步技術(shù)亩鬼。在提高安全性的精神下殖告,這個(gè)模型將幫助你在Swift中寫出更多可預(yù)知的代碼。