Swift里值類型和引用類型使用let和var申明屬性的區(qū)別

值類型

在 Swift 中,所有的基本類型:整數(shù)(Integer)址儒、浮 點(diǎn)數(shù)(floating-point)演训、布爾值(Boolean)、字符串(string)汁咏、數(shù)組(array)和字典(dictionary)亚斋,都是 值類型,并且在底層都是以結(jié)構(gòu)體的形式所實(shí)現(xiàn)攘滩。

在 Swift 中帅刊,所有的結(jié)構(gòu)體和枚舉類型都是值類型。這意味著它們的實(shí)例漂问,以及實(shí)例中所包含的任何值類型屬 性赖瞒,在代碼中傳遞的時(shí)候都會被復(fù)制。

引用類型

除了值類型蚤假,都是引用類型栏饮,在Swift中類就是引用類型,和Java類似磷仰,在OC中擁不擁有isa指針的區(qū)別袍嬉。

與值類型不同,引用類型在被賦予到一個(gè)變量灶平、常量或者被傳遞到一個(gè)函數(shù)時(shí)伺通,其值不會被拷貝。因此民逼,引用的
是已存在的實(shí)例本身而不是其拷貝

1. 值類型 let var

值類型和OC中的基本數(shù)據(jù)類型一致泵殴,其內(nèi)存在棧空間里拼苍,當(dāng)作用域結(jié)束系統(tǒng)自動回收笑诅。

  • 用let去申明一個(gè)值類型调缨,對該變量進(jìn)行拷貝,保證這個(gè)變量的值不被修改吆你;
  • 用var去申明一個(gè)值類型弦叶,對該變量進(jìn)行拷貝,新變量可進(jìn)行修改值妇多,不影響原來的變量伤哺;
    Value Type
2. 引用類型 let var

除了值類型,其他都是引用類型者祖,引用類型的實(shí)例被稱之為對象立莉,值類型的實(shí)例只能被稱之為實(shí)例,申明的變量在椘呶剩空間里是一個(gè)引用蜓耻,創(chuàng)建的對象放在堆空間里,引用指向堆空間創(chuàng)建的對象械巡。

  • 用let申明一個(gè)引用類型刹淌,只能保證該實(shí)例不被指向其他實(shí)例;
  • 用var申明一個(gè)引用類型讥耗,這個(gè)實(shí)例可以被其他實(shí)例賦值有勾,就是該實(shí)例的引用會指向新值;

創(chuàng)建3個(gè)變量

let origin = ViewMode()
let passLetOrigin = origin
var passVarOrigin = origin

其內(nèi)存情況古程,如圖所示蔼卡,3個(gè)變量的內(nèi)存地址一致,引用都指向同一個(gè)堆空間里的創(chuàng)建對象


Referance Type

我們再創(chuàng)建一個(gè)對象otherObject

let otherObject = ViewMode()

這時(shí)候內(nèi)存里應(yīng)該是這樣的


otherObject

otherObject指向自己新創(chuàng)建的對象

如果將passVarOrigin = otherObject內(nèi)存會怎樣呢籍琳?


passToVarOrigin.gif

如圖菲宴,passVarOrigin的指針地址變成了0x456,而引用也指向了otherObject的對象趋急。

實(shí)際上PassvarOrigin進(jìn)行了一次析構(gòu) 將就對象銷毀了 再進(jìn)行賦值
這時(shí)候修改實(shí)例變量

        origin.name = "1.0"
        passLetOrigin.name = "2.0"
        passVarOrigin.name = "3.0"
        
        print("origin.name: \(origin.name)")
        print("passLetOrigin.name: \(passLetOrigin.name)")
        print("passVarOrigin.name: \(passVarOrigin.name)")
        print("-----------------------")
        print("origin.name: \(origin.name)")
        print("passLetOrigin.name: \(passLetOrigin.name)")

打印結(jié)果:

origin.name: Optional("2.0")//因?yàn)閛rigin與passLetOrigin指向同一個(gè)實(shí)例,passLetOrigin.name后被修改為2.0势誊,所以沒有打印1.0
passLetOrigin.name: Optional("2.0")
passVarOrigin.name: Optional("3.0")
-----------賦值后------------
origin.name: Optional("2.0")//
passLetOrigin.name: Optional("2.0")

賦值后呜达,origin.name和passLetOrigin.name的值并沒有受到passVarOrigin.name的更改而改變。

值類型和引用類型的作用

選擇值類型而不是引用類型的一個(gè)主要原因是能讓你的代碼變得更加簡單粟耻。你在任何情況下用一個(gè)值類型查近,都能保證值不會在其他代碼里被改變,這在多線程很有用挤忙,保證其線程安全霜威。
在值不被修改的情況下,值類型和引用類型看起來是完全一樣的册烈。
你也許會想戈泼,寫一個(gè)完全不可變的類,這或許是有價(jià)值的,使用Cocoa的NSObject能簡化這個(gè)過程大猛,并且能很好地保持原有的語義扭倾。
現(xiàn)在,你能通過使用不可變的存儲屬性挽绩,以及避免暴露修改數(shù)據(jù)的接口膛壹,從而在Swift里實(shí)現(xiàn)一個(gè)不可變的類。事實(shí)上唉堪,大多數(shù)的Cocoa類模聋,比如NSURL等,都被設(shè)計(jì)為不可變的類唠亚,然而撬槽,Swift當(dāng)前并沒有提供任何語言機(jī)制去強(qiáng)制申明一個(gè)類不可改變(比如子類化就能修改一個(gè)類的實(shí)現(xiàn)),只有結(jié)構(gòu)體和枚舉才是強(qiáng)制不可變的趾撵。

如何選擇

所以如果你想要創(chuàng)建一個(gè)新的類型侄柔,你怎么選擇?當(dāng)你寫Cocoa程序的時(shí)候占调,大多數(shù)APIs都需要從NSObject繼承暂题,你就已經(jīng)是一個(gè)類了(引用類型),針對其他情況究珊,這里有些指導(dǎo)規(guī)則:
使用值類型薪者,當(dāng):
通過使用==去比較實(shí)例的數(shù)據(jù)
你想得到一個(gè)實(shí)例的獨(dú)立副本
數(shù)據(jù)在多線程環(huán)境下被修改

使用引用類型(比如使用一個(gè)類),當(dāng):
通過使用===去判斷兩個(gè)實(shí)例是否恒等
你想要創(chuàng)建一個(gè)共享的剿涮,可變的對象
在Swift里言津,Array、String和Dictionary都是值類型取试,他們的行為和C語言中的int類似悬槽,每個(gè)實(shí)例都有自己的數(shù)據(jù),你不需要額外做任何事情瞬浓,比如做一個(gè)顯式的copy初婆,防止其他代碼在你不知情的情況下修改等,更重要的是猿棉,你能安全地在線程間傳遞它磅叛,而不需要使用同步技術(shù)。在提高安全性的精神下萨赁,這個(gè)模型將幫助你在Swift中寫出更多可預(yù)知的代碼弊琴。

自己的思考就是結(jié)構(gòu)體和類的選擇,而他們最大的區(qū)別在于是否需要繼承杖爽,官方指出敲董,數(shù)據(jù)結(jié)構(gòu)簡單紫皇,數(shù)據(jù)較小使用結(jié)構(gòu)體;

參考:

Value and Reference Types

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末臣缀,一起剝皮案震驚了整個(gè)濱河市坝橡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌精置,老刑警劉巖计寇,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異脂倦,居然都是意外死亡番宁,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門赖阻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蝶押,“玉大人,你說我怎么就攤上這事火欧∑宓纾” “怎么了?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵苇侵,是天一觀的道長赶盔。 經(jīng)常有香客問我,道長榆浓,這世上最難降的妖魔是什么于未? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮陡鹃,結(jié)果婚禮上烘浦,老公的妹妹穿的比我還像新娘。我一直安慰自己萍鲸,他們只是感情好闷叉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著猿推,像睡著了一般片习。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蹬叭,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機(jī)與錄音状知,去河邊找鬼秽五。 笑死,一個(gè)胖子當(dāng)著我的面吹牛饥悴,可吹牛的內(nèi)容都是我干的坦喘。 我是一名探鬼主播盲再,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼瓣铣!你這毒婦竟也來了答朋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤棠笑,失蹤者是張志新(化名)和其女友劉穎梦碗,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蓖救,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡洪规,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了循捺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斩例。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖从橘,靈堂內(nèi)的尸體忽然破棺而出念赶,到底是詐尸還是另有隱情,我是刑警寧澤恰力,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布叉谜,位于F島的核電站,受9級特大地震影響牺勾,放射性物質(zhì)發(fā)生泄漏正罢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一驻民、第九天 我趴在偏房一處隱蔽的房頂上張望翻具。 院中可真熱鬧,春花似錦回还、人聲如沸裆泳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽工禾。三九已至,卻和暖如春蝗柔,著一層夾襖步出監(jiān)牢的瞬間闻葵,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工癣丧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留槽畔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓胁编,卻偏偏與公主長得像厢钧,于是被迫代替她去往敵國和親鳞尔。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容