Swift 內(nèi)存管理與循環(huán)引用問題(weak、unowned)

之前我在CSDN上寫過一篇博客:OC內(nèi)存管理踱蠢、ARC火欧、property屬性、__strong、__weak布隔、__blockhttp://blog.csdn.net/u012297622/article/details/50698286离陶,大家有興趣的可以去看看稼虎。

今天我們來整理一下Swift的內(nèi)存管理與循環(huán)引用的解決問題-weak衅檀、unowned:

內(nèi)存管理

swift的內(nèi)存管理也是使用的ARC(自動引用技術(shù)):當(dāng)我們初始化創(chuàng)建一個對象實例的時候,swift就會替我們管理和分配內(nèi)存,此時的引用計數(shù)為1,當(dāng)對其進(jìn)行init(copy/mutableCopy)時,引用計數(shù)會+1霎俩,而當(dāng)實例被銷毀時哀军,引用計數(shù)就會-1。當(dāng)系統(tǒng)檢測到引用計數(shù)為0的時候打却,就會釋放掉這個內(nèi)存杉适。

但是,這種引用計數(shù)會產(chǎn)生一個問題就是循環(huán)引用:

循環(huán)引用

class A {

? ? ? ?var b:B?

? ? ? init() { print("A初始化") }

? ? ?deinit { print("A析構(gòu)掉") }

}

class B {

? ? ? ?var a:A?

? ? ? ?init() { print("B初始化") }

? ? ? ?deinit { print("B析構(gòu)掉") }

}

var a:A?; ? a = A()

var b:B?; ? b = B()

a!.b = b; ? b!.a = a

a = nil;? ? b = nil

你會發(fā)現(xiàn)柳击,A和B的析構(gòu)函數(shù)deinit都沒有調(diào)用猿推,因為當(dāng)a執(zhí)行析構(gòu)的時候,b.a還在對其進(jìn)行引用捌肴,當(dāng)b析構(gòu)的時候蹬叭,a.b也在對b進(jìn)行引用。這時候解決的方法就是對其中的某一個聲明進(jìn)行若引用状知,即加上weak:

weak var b:B?

另外一種造成循環(huán)引用的問題就是閉包:閉包中對任何元素的引用都會被閉包自動持有秽五,如果我們在閉包中需要使用self的話,那就相當(dāng)于閉包對self持有饥悴,而block又是被self直接或間接持有坦喘,這樣就造成了循環(huán)引用。例如下面的代碼:

class C{

? ? ? ?var name:String

? ? ? ?lazy var block:()->() = {

? ? ? ?print(self.name )

}

init(name:String) {

? ? ? ?self.name = name

? ? ? ?print("C初始化")

}

deinit {

print("C析構(gòu)")

}

}

var c:C? = C(name:"c")

c?.block()

c = nil

這里C的析構(gòu)函數(shù)也是沒有執(zhí)行的西设。block是self的屬性瓣铣,block里面又對self持有,這就形成了循環(huán)引用贷揽。所以這里我們可以使用unowned棠笑,也可以使用weak:

//unowned

lazy var block:()->() = {[unowned self] in

print(self.name)

}

//weak

lazy var block:()->() = {[weak self] in

if let strongSelf = self{

print(strongSelf.name)

}

}

那么這兩個使用有什么區(qū)別呢?接下來看一個例子:

class C{

var name:String

lazy var block:()->() = {[unowned self] in

print(self.name)

}

init(name:String) {

self.name = name

print("C初始化")

}

deinit {

print("C析構(gòu)")

}

}

class D{

var block:(()->())!

init(callBack:(()->())?) {

self.block = callBack!

print("D構(gòu)造")

}

deinit {

print("D析構(gòu)")

}

}

var c:C? = C(name:"c")

var d = D.init(callBack:c?.block)

c!.block()

c = nil

d.block()

這里當(dāng)你運行到 d.block()的時候擒滑,是會有一個error的

因為當(dāng)d.block()執(zhí)行的時候腐晾,c已經(jīng)被析構(gòu)掉了,而閉包里的self肯定也是不存在的丐一,是一個nil藻糖,這個時候執(zhí)行的話self.name就會報錯。所以在我們不確定是否有外部變量在持有這個block的時候库车,我們就應(yīng)該使用weak更為安全巨柒,因為使用weak的話self.name需要改成可選性的self?.name,這個時候self?.name肯定就為nil了。所以換成weak之后洋满,在playground里的d.block()就不會有錯誤了晶乔,而且block也是會正常執(zhí)行的,只不過print(self?.name)打印出來為nil牺勾。

歡迎大家訪問我的github:https://github.com/FCF5646448正罢,如果有能幫助到大家的地方,可以鼓勵我個小星星哦

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末驻民,一起剝皮案震驚了整個濱河市翻具,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌回还,老刑警劉巖裆泳,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異柠硕,居然都是意外死亡工禾,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門蝗柔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闻葵,“玉大人,你說我怎么就攤上這事诫咱◇舷叮” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵坎缭,是天一觀的道長竟痰。 經(jīng)常有香客問我,道長掏呼,這世上最難降的妖魔是什么坏快? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮憎夷,結(jié)果婚禮上莽鸿,老公的妹妹穿的比我還像新娘。我一直安慰自己拾给,他們只是感情好祥得,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蒋得,像睡著了一般级及。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上额衙,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天饮焦,我揣著相機與錄音怕吴,去河邊找鬼。 笑死县踢,一個胖子當(dāng)著我的面吹牛转绷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播硼啤,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼议经,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了丙曙?” 一聲冷哼從身側(cè)響起爸业,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎亏镰,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拯爽,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡索抓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了毯炮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逼肯。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖桃煎,靈堂內(nèi)的尸體忽然破棺而出篮幢,到底是詐尸還是另有隱情,我是刑警寧澤为迈,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布三椿,位于F島的核電站,受9級特大地震影響葫辐,放射性物質(zhì)發(fā)生泄漏搜锰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一耿战、第九天 我趴在偏房一處隱蔽的房頂上張望蛋叼。 院中可真熱鬧,春花似錦剂陡、人聲如沸狈涮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽歌馍。三九已至,卻和暖如春纤泵,著一層夾襖步出監(jiān)牢的瞬間骆姐,已是汗流浹背镜粤。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留玻褪,地道東北人肉渴。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像带射,于是被迫代替她去往敵國和親同规。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

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