內(nèi)存管理不管是在ObjectC 還是swift上雹有,在開發(fā)過程中都是我們需要關(guān)注的一個(gè)重點(diǎn)。剛好學(xué)習(xí)到臼寄,做此筆記
1.類的初始化和類的銷毀
1.類初始化使用init關(guān)鍵字霸奕;
2.類的銷毀使用deinit關(guān)鍵字。
eg:
class Student{
let name : String
var website = "JournalDev"
//初始化
init(name:String){
self.name = name
print("\(name) is being initialized")
}
//釋放變量:自動(dòng)釋放吉拳,不能手動(dòng)調(diào)用质帅。
deinit {
print("\(name) is being deinitialized")
print("\(website) is being deinitialized")
}
}
var s : Student? = Student(name:"Chloe")
//打印結(jié)果:Chloe is being initialized
var reference = s//此時(shí)reference引用了s
var reference2 = reference//reference2引用了reference
//因?yàn)轭愂且妙愋停藭r(shí)留攒,s被reference引用煤惩;reference被reference2引用;
reference = nil//reference is nil炼邀;沒有走deinit方法
s = nil//s is nil魄揉;沒有走deinit方法
reference2 = nil//走deinit方法
//打印結(jié)果:
//Chloe is being deinitialized
//JournalDev is being deinitialized
//從上面的例子可以看出,只有對(duì)類的引用全部無(wú)效時(shí)拭宁,類才被釋放洛退。
2.循環(huán)引用(強(qiáng)引用)
因?yàn)轭愂且妙愋桶旮院苋菀自斐裳h(huán)引用,導(dǎo)致類不能被釋放兵怯;
eg:
class Major {
let name : String
var university : University?//引用了University類
init(name : String) {
self.name = name
}
deinit {
print("\(name) is being deinitialized")
}
}
class University{
let uniName : String
init(uniName : String) {
self.uniName = uniName
}
var major : Major?//引用了Major類
deinit {
print("University \(uniName) is being deinitialized")
}
}
//Major類和University此時(shí)是循環(huán)引用狀態(tài)〔守埃現(xiàn)在我們對(duì)兩個(gè)類進(jìn)行初始化
var meMajor: Major?
var uni: University?
meMajor = Major(name: "John Doe")
uni = University(uniName: "IIT")
meMajor?.university = uni
uni?.student = meMajor
meMajor = nil
uni = nil
當(dāng)我們給meMajor和uni都置為nil時(shí),此時(shí)發(fā)現(xiàn)Major和University都沒有被釋放媒区;然后我們看一下怎么解決驼仪。
先了解一下引用類型:
引用類型有三種:strong、weak袜漩、unowned reference;
(1)strong:強(qiáng)引用是默認(rèn)情況下創(chuàng)建的引用的標(biāo)準(zhǔn)類型绪爸。
(2)weak:弱引用允許創(chuàng)建實(shí)例,但不計(jì)入弧的引用計(jì)數(shù)噪服。通常毡泻,當(dāng)一個(gè)引用的生存期比另一個(gè)引用短時(shí),應(yīng)該將其標(biāo)記為弱引用粘优。弱引用可以為nil仇味。
(3)unowned references:無(wú)主引用與弱引用類似,只是它們用于比其他引用具有更長(zhǎng)生存期的引用雹顺。只有在絕對(duì)確定引用確實(shí)存在時(shí)才應(yīng)該使用無(wú)主引用丹墨,否則如果在nil引用上調(diào)用它,它將崩潰嬉愧。也就是無(wú)主引用不可以置為nil贩挣。
解決辦法:所以上面的循環(huán)引用,我們可以用弱引用或者無(wú)主引用來(lái)解決循環(huán)引用問題没酣。只要在屬性前面添加weak關(guān)鍵字就可以
class Major {
let name : String
weak var university : University?
init(name : String) {
self.name = name
}
deinit {
print("\(name) is being deinitialized")
}
}
class University{
let uniName : String
init(uniName : String) {
self.uniName = uniName
}
weak var major : Major?
deinit {
print("University \(uniName) is being deinitialized")
}
}
var meMajor: Major?
var uni: University?
meMajor = Major(name: "John Doe")
uni = University(uniName: "IIT")
meMajor?.university = uni
uni?.major = meMajor
meMajor = nil
uni = nil
//打印結(jié)果:
//University IIT is being deinitialized
//John Doe is being deinitialized
3.閉包循環(huán)引用
使用捕獲列表解析閉包中的引用循環(huán)王财;閉包是引用類型,所以也會(huì)造成循環(huán)引用裕便。
閉包中使用了[unowned self]和[weak self]都不會(huì)造成閉包循環(huán)引用問題绒净。
class User {
let name: String
let skill: String
//會(huì)造成循環(huán)引用
// lazy var summary: () -> String = {
// return "\(self.name) (\(self.skill))"
// }
//不會(huì)造成循環(huán)引用
// lazy var summary: () -> String = {[unowned self] in
// return "\(self.name) (\(self.skill))"
// }
//也不會(huì)造成循環(huán)引用
lazy var summary:() -> String = {[weak self] in
guard let weakSelf = self else { return }
return "\(weakSelf.name) (\(weakSelf.skill))"
}
init(name: String, skill: String) {
self.name = name
self.skill = skill
}
deinit {
print("Deallocated User")
}
}
var name: User? = User(name: "Anupam", skill: "Swift")
name?.summary()
name = nil