循環(huán)引用鼎兽,即 A 強引用 B,B 強引用 A铣除,對象銷毀時會出現(xiàn)谚咬,A、B都無法銷毀尚粘,因為A择卦、B在相互等對方銷毀,可是誰也沒有辦法先銷毀
一郎嫁、采用弱引用 避免循環(huán)引用
引用有3種情況:
1互捌、默認(rèn)強引用,即不做任何修飾
2行剂、弱引用 [weak self]秕噪,在對象被被釋放后會將 self =nil,與 OC weak修飾一樣效果
3厚宰、無宿主引用 [unowned self]腌巾,對象釋放后遂填,不會設(shè)置為 nil,非安全調(diào)用會導(dǎo)致閃退澈蝙,與 OC assign 修飾類似
class Util : NSObject {
var block : (()->())?
static let shared : Util = {
let o = Util()
return o
}()
func doSomething(callback: @escaping()->Void) {
block = callback
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 5, execute: {
print("callback ()->()")
(self.block ?? {print("completion==nil")})()
})
}
}
class LoginViewController: UIViewController {
var domain: LoginDomain!
deinit {
print("\(self) 釋放")
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
print(self.domain.title)
// 弱引用吓坚,不會導(dǎo)致循環(huán)引用問題
/*
1、Util.shared 是單例灯荧,進程存在則不會被銷毀
2礁击、doSomething 回調(diào)用 會被 Util.shared 單例【強引用持有】
3、doSomething 回調(diào)中如果再強引用 self 時逗载,就會導(dǎo)致相互 controller與Util.shared 相互持有對方哆窿,從而導(dǎo)致無法釋放
*/
// Util.shared.doSomething {
// print("do()->Void " + self.domain.title)
// }
/*
4、如果 doSomething 回調(diào)使用 弱引用厉斟,則 callback 不會強制持有 self(controller)挚躯,及時 callback 被util.shared持有不釋放,依然不會影響 controller 的 deinit
5擦秽、弱引用可以使用 guard 簡潔寫法码荔,然而 該寫法可能會導(dǎo)致業(yè)務(wù)執(zhí)行不完整的請求,guard let self = self else {return} 如果controller被釋放了感挥,callback 就直接 return了缩搅,后續(xù)業(yè)務(wù)無法執(zhí)行
*/
Util.shared.doSomething {[weak self] in
// 通俗寫法 guard let self = self else {return}
guard let self = self else {
print("self 已經(jīng)釋放")
return
}
print("do()->Void guard " + self.domain.title)
}
/*
6、不使用 guard触幼,寫法不那么優(yōu)雅誉己,需要 ?或 域蜗??逐個判別對象
*/
// Util.shared.doSomething { [weak self]in
// if self == nil {
// print("self 已經(jīng)釋放")
// }
// print("do()->Void " + (self?.domain.title ?? "") )
// }
}
}