與值類型不同,引用類型在被賦予到一個(gè)變量,常量或者被傳遞到一個(gè)函數(shù)時(shí),操作的并不是其拷貝。因此,引用的是已存在的實(shí)例本身而不是其拷貝。
請(qǐng)看下面這個(gè)示例,其使用了之前定義的VideoMode類:
let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0
以上示例中,聲明了一個(gè)名為tenEighty的常量,其引用了一個(gè)VideoMode類的新實(shí)例。在之前的示例中,這個(gè)視頻模式(video mode)被賦予了HD分辨率(1920*1080)的一個(gè)拷貝(hd)。同時(shí)設(shè)置為交錯(cuò)(interlaced),命名為“1080i”。最后,其幀率是25.0幀每秒。
然后,tenEighty 被賦予名為alsoTenEighty的新常量,同時(shí)對(duì)alsoTenEighty的幀率進(jìn)行修改:
let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0
因?yàn)轭愂且妙愋?,所?code style="box-sizing: border-box; -webkit-tap-highlight-color: transparent; -webkit-font-smoothing: antialiased; font-family: Monaco, Menlo, Consolas, 'Courier New', monospace; font-size: 13px; padding: 0px 5px; color: rgb(199, 37, 78); background-color: rgb(248, 248, 248); white-space: nowrap; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; margin: 0px 2px; border: 1px solid rgb(234, 234, 234);">tenEight和alsoTenEight實(shí)際上引用的是相同的VideoMode實(shí)例。換句話說(shuō),它們只是同一個(gè)實(shí)例的兩種叫法。
下面,通過(guò)查看tenEighty的frameRate屬性,我們會(huì)發(fā)現(xiàn)它正確的顯示了基本VideoMode實(shí)例的新幀率,其值為30.0:
println("The frameRate property of tenEighty is now \(tenEighty.frameRate)")
// 輸出 "The frameRate property of theEighty is now 30.0"
需要注意的是tenEighty和alsoTenEighty被聲明為常量((constants)而不是變量。然而你依然可以改變tenEighty.frameRate和alsoTenEighty.frameRate,因?yàn)檫@兩個(gè)常量本身不會(huì)改變。它們并不儲(chǔ)存這個(gè)VideoMode實(shí)例,在后臺(tái)僅僅是對(duì)VideoMode實(shí)例的引用。所以,改變的是被引用的基礎(chǔ)VideoMode的frameRate參數(shù),而不改變常量的值。
因?yàn)轭愂且妙愋停锌赡苡卸鄠€(gè)常量和變量在后臺(tái)同時(shí)引用某一個(gè)類實(shí)例。(對(duì)于結(jié)構(gòu)體和枚舉來(lái)說(shuō),這并不成立。因?yàn)樗鼈冏髦殿愋?,在被賦予到常量,變量或者傳遞到函數(shù)時(shí),總是會(huì)被拷貝。)
如果能夠判定兩個(gè)常量或者變量是否引用同一個(gè)類實(shí)例將會(huì)很有幫助。為了達(dá)到這個(gè)目的,Swift 內(nèi)建了兩個(gè)恒等運(yùn)算符:
以下是運(yùn)用這兩個(gè)運(yùn)算符檢測(cè)兩個(gè)常量或者變量是否引用同一個(gè)實(shí)例:
if tenEighty === alsoTenTighty {
println("tenTighty and alsoTenEighty refer to the same Resolution instance.")
}
//輸出 "tenEighty and alsoTenEighty refer to the same Resolution instance."
請(qǐng)注意“等價(jià)于”(用三個(gè)等號(hào)表示,===) 與“等于”(用兩個(gè)等號(hào)表示,==)的不同:
當(dāng)你在定義你的自定義類和結(jié)構(gòu)體的時(shí)候,你有義務(wù)來(lái)決定判定兩個(gè)實(shí)例“相等”的標(biāo)準(zhǔn)。在章節(jié)運(yùn)算符函數(shù)(Operator Functions)中將會(huì)詳細(xì)介紹實(shí)現(xiàn)自定義“等于”和“不等于”運(yùn)算符的流程。
如果你有 C,C++ 或者 Objective-C 語(yǔ)言的經(jīng)驗(yàn),那么你也許會(huì)知道這些語(yǔ)言使用指針來(lái)引用內(nèi)存中的地址。一個(gè) Swift 常量或者變量引用一個(gè)引用類型的實(shí)例與 C 語(yǔ)言中的指針類似,不同的是并不直接指向內(nèi)存中的某個(gè)地址,而且也不要求你使用星號(hào)(*)來(lái)表明你在創(chuàng)建一個(gè)引用。Swift 中這些引用與其它的常量或變量的定義方式相同。