閉包中的循環(huán)引用可通過weak與unowned解決
weak引用時:必須是可選類型的var,因?yàn)閷?shí)例銷毀后镀岛,ARC會自動將弱引用設(shè)置為nil友驮。此時不會觸發(fā)屬性觀察器(willSet/didSet)
unowned引用時: 不會產(chǎn)生強(qiáng)引用卸留,實(shí)例銷毀后仍然存儲著實(shí)例的內(nèi)存地址耻瑟。如果在實(shí)例銷毀后繼續(xù)訪問無主引用,會產(chǎn)生運(yùn)行時錯誤(野指針)
class Person {
? ? var?fn: (() -> ())?
? ? func?run() {
? ? ? ? print("Person run")
? ? ? ? fn?()
? ? }
? ? deinit{
? ? ? ? print("Person deinit")
? ? }
}
當(dāng)另一個頁面調(diào)用閉包時谆构,以下代碼會造成循環(huán)引用,不會來到deinit方法
? ? var?id = 1
? ? func?test() {
? ? ? ? p.fn = { ()?in
? ? ? ? ? ? print("調(diào)用了person fn",self.id)
? ? ? ? }
? ? ? ? p.run()
? ? }
一搬素、使用weak解決循環(huán)引用
寫法一
寫法二
二摸屠、使用unowned解決循環(huán)引用
寫法一
寫法二
如果是lazy屬性閉包調(diào)用,則不用考慮循環(huán)引用的問題戒傻,因?yàn)檎{(diào)用后,閉包的生命周期就結(jié)束了
三艺挪、weak與unowned的區(qū)別
1、使用weak兵扬,在閉包中訪問外界變量返回可選類型麻裳;而unowned則返回原類型
2、在實(shí)例銷毀后繼續(xù)訪問(unowned)引用,會產(chǎn)生運(yùn)行時錯誤(野指針),如下圖所示
unowned var up = Person()
? ? func?test() {
? ? ? ? up.run()
? ? }