objective-C不像C#、Java那樣使用垃圾回收機制回收內(nèi)存(GC),而是使用引用計數(shù)器機制管距內(nèi)存。
引用計數(shù)器
引用計數(shù)器的原理:每個對象都有一個計數(shù)器,當對象創(chuàng)建或被引用時計數(shù)器加1,當引用取消時計數(shù)器減1,計數(shù)器為0時,系統(tǒng)自動銷毀該對象。
內(nèi)存釋放原則
誰創(chuàng)建誰釋放
屬性與內(nèi)存管理
使用@property關(guān)鍵字聲明屬性,實際上是讓系統(tǒng)為這個屬性合成getter和setter方法。
關(guān)于assign、retain和copy
assign用于基本數(shù)據(jù)類型,它合成的setter類似
-(void)setObjA:(ClassA? *)a
{
objA? =? a;
}
retain
-(void)setObjA:(ClassA? *)a
{
If(objA != a)
{
[objA? release];
objA? =? a;
[objA? retain];? //對象的retain count 加1
}
}
copy
-(void)setObjA:(ClassA? *)a
{
ClassA? * temp? =? objA;
objA? =? [a?? copyWithZone:nil];
[temp? release];
}
自動釋放池
自動內(nèi)存釋放使用@auyoreleasepool關(guān)鍵字聲明一個代碼塊,當代碼塊執(zhí)行完之后,在塊中調(diào)用autorelease方法的對象都會自動調(diào)用一次release方法。這樣就起到了自動釋放的作用,同時對象銷毀的過程也得到了延遲。
自動釋放池實質(zhì)是當自動釋放池銷毀后調(diào)用release方法,不一定能銷毀對象。
由于自動釋放池最后統(tǒng)一銷毀對象,因此如果一個操作比較占用內(nèi)存,最好不要放到自動釋放池
注意事項
ARC雖然能夠解決大部分的內(nèi)存泄露問題,但是仍然有些地方是我們需要注意的。
循環(huán)引用兩個對象互相強引用了對方,從而導(dǎo)致了誰也釋放不了誰的內(nèi)存泄漏問題。比如delegate對象需要設(shè)置weak,否則可能出現(xiàn)對象循環(huán)引用的問題。block如果使用了外部的局部變量或self,需要使用關(guān)鍵字weak。NSTime使用時也要注意,在dealloc前,調(diào)用invaildate方法。延時執(zhí)行方法也是,父類銷毀前先取消自身。