除了類的實(shí)例之間會(huì)產(chǎn)生循環(huán)強(qiáng)引用之外,在閉包和類之間也可能產(chǎn)生強(qiáng)引用。這種強(qiáng)引用出現(xiàn)在將閉包賦值給類的屬性把跨,同時(shí)在閉包內(nèi)部引用了這個(gè)類的實(shí)例時(shí)丧没。究其原因鹰椒,是因?yàn)殚]包也是引用類型,當(dāng)在閉包內(nèi)部引用類的實(shí)例屬性和方法時(shí)呕童,閉包默認(rèn)對(duì)類的實(shí)例擁有強(qiáng)引用漆际。要解決這個(gè)問(wèn)題,需要使用閉包捕獲對(duì)象夺饲。
下面這個(gè)例子是一個(gè)實(shí)例和閉包相互之間的強(qiáng)引用
class Student{
var name:String?
var score:Int
lazy var level:(Void) -> String = {
switch self.score{
case 0..<60:
return "C"
case 60..<85:
return "B"
case 85..<100:
return "A"
default:
return "D"
}
}
init(name:String,score:Int){
self.name = name
self.score = score
}
deinit {
print("Student 對(duì)象:\(name!)被銷毀了")
}
}
var xiaoMing:Student? = Student(name:"小明",score:86)
print("\(xiaoMing!.name!)成績(jī)水平為:\(xiaoMing!.level())")
xiaoMing = nil
// 當(dāng)實(shí)例被賦予nil時(shí)奸汇,沒(méi)有調(diào)用析構(gòu)函數(shù)
解決這個(gè)問(wèn)題我們使用捕獲列表
[weak self,unowned delegate = self.delegate]
[unowned self, weak delegate = self.delegate!]
下面重新寫(xiě)一個(gè)
class Student2{
var name:String?
var score:Int
lazy var level:(Void) -> String = {
[weak self] in
switch self!.score{
case 0..<60:
return "C"
case 60..<85:
return "B"
case 85..<100:
return "A"
default:
return "D"
}
}
init(name:String,score:Int){
self.name = name
self.score = score
}
deinit {
print("Student對(duì)象:\(name!)被銷毀了")
}
}
var xiaoMing2:Student2? = Student2(name:"小明",score:86)
print("\(xiaoMing2!.name!)成績(jī)水平為:\(xiaoMing2!.level())")
xiaoMing2 = nil
通過(guò)[weak self] in 在閉包前增加了捕獲列表的定義。并且由于self可能為nil往声,因?yàn)槭莣eak的弱引用擂找,因此需要嘆號(hào)解包self使用,