Swift內(nèi)存管理:
管理引用類型的內(nèi)存, 不會(huì)管理值類型, 值類型不需要管理
內(nèi)存管理原則: 當(dāng)沒有任何強(qiáng)引用指向?qū)ο? 系統(tǒng)會(huì)自動(dòng)銷毀對象(默認(rèn)情況下所有的引用都是強(qiáng)引用),如果做到該原則: ARC
class Person {
var name:String
init(name:String){
self.name = name
}
deinit{
print("deinit")
}
}
var p:Person? = Person(name: "lnj")
//p = nil
weak弱引用
class Person2 {
var name:String
init(name:String){
self.name = name
}
deinit{
print("deinit")
}
}
// 強(qiáng)引用, 引用計(jì)數(shù)+1
var strongP = Person2(name: "lnj") // 1
var strongP2 = strongP // 2
// 弱引用, 引用計(jì)數(shù)不變
// 如果利用weak修飾變量, 當(dāng)對象釋放后會(huì)自動(dòng)將變量設(shè)置為nil
// 所以利用weak修飾的變量必定是一個(gè)可選類型, 因?yàn)橹挥锌蛇x類型才能設(shè)置為nil
weak var weakP:Person2? = Person2(name: "lnj")
if let p = weakP{
print(p)
}else
{
print(weakP)
}
unowned無主引用 , 相當(dāng)于OC unsafe_unretained
unowned和weak的區(qū)別:
1.利用unowned修飾的變量, 對象釋放后不會(huì)設(shè)置為nil. 不安全
利用weak修飾的變量, 對象釋放后會(huì)設(shè)置為nil
2.利用unowned修飾的變量, 不是可選類型
利用weak修飾的變量, 是可選類型
什么時(shí)候使用weak?
什么時(shí)候使用unowned?
class Person3 {
var name:String
init(name:String){
self.name = name
}
deinit{
print("deinit")
}
}
unowned var weakP3:Person3 = Person3(name: "lnj")
循環(huán)引用
ARC不是萬能的, 它可以很好的解決內(nèi)存問題, 但是在某些場合不能很好的解決內(nèi)存泄露問題
例如兩個(gè)或多個(gè)對象之間的循環(huán)引用問題
class Person4 {
let name:String // 姓名
// 人不一定有公寓
weak var apartment: Apartment? // 公寓
init(name:String){
self.name = name
}
deinit{
print("\(self.name) deinit")
}
}
class Apartment {
let number: Int // 房間號
var tenant: Person4? // 租客
init(number:Int){
self.number = number
}
deinit{
print("\(self.number) deinit")
}
}
var p4:Person4? = Person4(name: "lnj")
var a4:Apartment? = Apartment(number:888)
p4!.apartment = a4 // 人有一套公寓
a4!.tenant = p4! // 公寓中住著一個(gè)人
// 兩個(gè)對象沒有被銷毀, 但是我們沒有辦法訪問他們了. 內(nèi)存泄露
p4 = nil
a4 = nil
class Person5 {
let name:String // 姓名
// 人不一定有信用卡
var card: CreditCard?
init(name:String){
self.name = name
}
deinit{
print("\(self.name) deinit")
}
}
class CreditCard{
let number: Int
// 信用卡必須有所屬用戶
// 當(dāng)某一個(gè)變量/常量必須有值, 一直有值, 那么可以使用unowned修飾
unowned let person: Person5
init(number:Int, person: Person5){
self.number = number
self.person = person
}
deinit{
print("\(self.number) deinit")
}
}
var p5:Person5? = Person5(name: "lnj")
var cc:CreditCard? = CreditCard(number: 8888888, person: p5!)
p5 = nil
cc = nil