swift使用arc (automatic reference counting)
記憶體管理在編譯期間就決定了
每個物件都有個retain count當沒人使用他就會歸0然後物件葛屁
預設是strong retain counting
但是strong有可能會造成記憶體漏失
class Pig {
var myMaster : Owner
deinit{
print("噢不 我要被煮來吃了")
}
}
class Owner {
var myCutePig : Pig
deinit{
print("主人要葛屁了")
}
var peter : Owner = Owner()
var lilRed : Pig = Pig()
peter.myCutePig = lilRed
lilRed.myMaster = peter
peter = nil
lilRed = nil
}
這樣就會造成Reference cycle
因為指定時彼此間是強引用
屬性要等到物件葛屁才會葛屁
但他們互相又有變數指向對方
所以咧~ 無解
一人之豬
直接佔據你的記憶體
使用weak跟unowned兩個關鍵字
鐵石心腸 加了weak的變數retain count是廢票
當這個變數指到的物件死去時會變nil
由於他有可能是nil所以宣告是必須是optional 並且不能是常數(let)
跟weak一樣是鐵石心腸 只是當變數指向的物件葛屁後,變數不會變nil
並且可以宣告常數(let)
所以有人存取葛屁的物件就會存取到他的記憶體位置
然後你的app就會崩潰
算是一個危險人物
如果希望是常數選unknowed
如果希望是變數選weak
如果希望它可以是nil 選weak
closures 也會造成 reference cycle
closures capture value
class Tea {
var name : String
var closureToSaySomething : (()->())!
init (_ teaName : String){
self.name = teaName
self.closureToSaySomething = {
print ("這是"+ self.name + "太好喝了吧")
}
}
func SayName(){
closureToSaySomething()
}
deinit {
print ("倒掉....")
}
}
var moMoTea : Tea = Tea("摸摸茶")
moMoTea = nil
當創造一個摸摸茶時,由於closures capture value,記住了self的記憶體,所以有兩個地方連結到self
一個是宣告的屬性
一個是closureToSaySomething
最後造成一杯倒不掉的摸摸茶
capture list
利用capture list指定特例讓在closures裡的特例變廢票
[//把特例擺在這裡]
Example:
closureToSaySomething = {
[weak weakMe = self] in
print ("這是"+ weakMe.name! + "太好喝了吧")
}