在上面的例子中,ARC 會(huì)跟蹤你所新創(chuàng)建的Person實(shí)例的引用數(shù)量,并且會(huì)在Person實(shí)例不再被需要時(shí)銷毀它。
然而,我們可能會(huì)寫(xiě)出這樣的代碼,一個(gè)類永遠(yuǎn)不會(huì)有0個(gè)強(qiáng)引用。這種情況發(fā)生在兩個(gè)類實(shí)例互相保持對(duì)方的強(qiáng)引用,并讓對(duì)方不被銷毀。這就是所謂的循環(huán)強(qiáng)引用。
你可以通過(guò)定義類之間的關(guān)系為弱引用或者無(wú)主引用,以此替代強(qiáng)引用,從而解決循環(huán)強(qiáng)引用的問(wèn)題。具體的過(guò)程在解決類實(shí)例之間的循環(huán)強(qiáng)引用中有描述。不管怎樣,在你學(xué)習(xí)怎樣解決循環(huán)強(qiáng)引用之前,很有必要了解一下它是怎樣產(chǎn)生的。
下面展示了一個(gè)不經(jīng)意產(chǎn)生循環(huán)強(qiáng)引用的例子。例子定義了兩個(gè)類:Person和Apartment,用來(lái)建模公寓和它其中的居民:
class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
deinit { println("\(name) is being deinitialized") }
}
class Apartment {
let number: Int
init(number: Int) { self.number = number }
var tenant: Person?
deinit { println("Apartment #\(number) is being deinitialized") }
}
每一個(gè)Person實(shí)例有一個(gè)類型為String,名字為name的屬性,并有一個(gè)可選的初始化為nil的apartment屬性。apartment屬性是可選的,因?yàn)橐粋€(gè)人并不總是擁有公寓。
類似的,每個(gè)Apartment實(shí)例有一個(gè)叫number,類型為Int的屬性,并有一個(gè)可選的初始化為nil的tenant屬性。tenant屬性是可選的,因?yàn)橐粭澒⒉⒉豢偸怯芯用瘛?/p>
這兩個(gè)類都定義了析構(gòu)函數(shù),用以在類實(shí)例被析構(gòu)的時(shí)候輸出信息。這讓你能夠知曉Person和Apartment的實(shí)例是否像預(yù)期的那樣被銷毀。
接下來(lái)的代碼片段定義了兩個(gè)可選類型的變量john和number73,并分別被設(shè)定為下面的Apartment和Person的實(shí)例。這兩個(gè)變量都被初始化為nil,并為可選的:
var john: Person?
var number73: Apartment?
現(xiàn)在你可以創(chuàng)建特定的Person和Apartment實(shí)例并將類實(shí)例賦值給john和number73變量:
john = Person(name: "John Appleseed")
number73 = Apartment(number: 73)
在兩個(gè)實(shí)例被創(chuàng)建和賦值后,下圖表現(xiàn)了強(qiáng)引用的關(guān)系。變量john現(xiàn)在有一個(gè)指向Person實(shí)例的強(qiáng)引用,而變量number73有一個(gè)指向Apartment實(shí)例的強(qiáng)引用:

現(xiàn)在你能夠?qū)⑦@兩個(gè)實(shí)例關(guān)聯(lián)在一起,這樣人就能有公寓住了,而公寓也有了房客。注意感嘆號(hào)是用來(lái)展開(kāi)和訪問(wèn)可選變量john和number73中的實(shí)例,這樣實(shí)例的屬性才能被賦值:
john!.apartment = number73
number73!.tenant = john
在將兩個(gè)實(shí)例聯(lián)系在一起之后,強(qiáng)引用的關(guān)系如圖所示:

不幸的是,將這兩個(gè)實(shí)例關(guān)聯(lián)在一起之后,一個(gè)循環(huán)強(qiáng)引用被創(chuàng)建了。Person實(shí)例現(xiàn)在有了一個(gè)指向Apartment實(shí)例的強(qiáng)引用,而Apartment實(shí)例也有了一個(gè)指向Person實(shí)例的強(qiáng)引用。因此,當(dāng)你斷開(kāi)john和上一篇:Swift元組下一篇:Swift閉包