內(nèi)存管理不管是在ObjectC 還是swift上,在開發(fā)過程中都是我們需要關(guā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")
}
//釋放變量:自動釋放,不能手動調(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//此時reference引用了s
var reference2 = reference//reference2引用了reference
//因為類是引用類型,此時,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
//從上面的例子可以看出,只有對類的引用全部無效時,類才被釋放。
2.循環(huán)引用(強引用)
因為類是引用類型,所以很容易造成循環(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此時是循環(huán)引用狀態(tài)?,F(xiàn)在我們對兩個類進(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時,此時發(fā)現(xiàn)Major和University都沒有被釋放;然后我們看一下怎么解決。
先了解一下引用類型:
引用類型有三種:strong、weak、unowned reference;
(1)strong:強引用是默認(rèn)情況下創(chuàng)建的引用的標(biāo)準(zhǔn)類型。
(2)weak:弱引用允許創(chuàng)建實例,但不計入弧的引用計數(shù)。通常,當(dāng)一個引用的生存期比另一個引用短時,應(yīng)該將其標(biāo)記為弱引用。弱引用可以為nil。
(3)unowned references:無主引用與弱引用類似,只是它們用于比其他引用具有更長生存期的引用。只有在絕對確定引用確實存在時才應(yīng)該使用無主引用,否則如果在nil引用上調(diào)用它,它將崩潰。也就是無主引用不可以置為nil。
解決辦法:所以上面的循環(huán)引用,我們可以用弱引用或者無主引用來解決循環(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án)引用。
閉包中使用了[unowned self]和[weak self]都不會造成閉包循環(huán)引用問題。
class User {
let name: String
let skill: String
//會造成循環(huán)引用
// lazy var summary: () -> String = {
// return "\(self.name) (\(self.skill))"
// }
//不會造成循環(huán)引用
// lazy var summary: () -> String = {[unowned self] in
// return "\(self.name) (\(self.skill))"
// }
//也不會造成循環(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