一、自動釋放池的原理及機制
一、O-C當中的內(nèi)存釋放,并不是像java/.net那樣有一個自動的釋放池,開發(fā)人員不用去關(guān)心有關(guān)內(nèi)存釋放的問題,O-C里面的自動釋放池比c語言的手動內(nèi)存管理要好一些,但是相對于java/.net來說又弱一些,所以說O-C當中的釋放屬于半自動的釋放池。
二、什么是自動釋放池
1、Autorelease pool
自動釋放池(Autorelease pool)是OC的一種內(nèi)存自動回收機制,可以將一些臨時變量通過自動釋放池來回收統(tǒng)一釋放
自動釋放池本事銷毀的時候,池子里面所有的對象都會做一次release操作
2、autorelease
任何OC對象只要調(diào)用autorelease方法,就會把該對象放到離自己最近的自動釋放池中(棧頂?shù)尼尫懦兀?/p>
三、如何創(chuàng)建一個自動釋放池
//ios5.0新方式
@autoreleasepool
{
}
//ios5.0之前的老方式
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc]init];
[pool release];
四、自動釋放池如何釋放對象內(nèi)存
黃金法則:如果對一個對象使用了alloc,[mutable]copy,retain,那么必須使用相應(yīng)的release或者autorelease.
當您向一個對象發(fā)送一個autorelease消息時,Cocoa就會將該對象的一個引用放入到最新的自動釋放池。它仍然是個正當?shù)膶ο?,因此自動釋放池定義的作用域內(nèi)的其它對象可以向它發(fā)送消息。當程序執(zhí)行到作用域結(jié)束的位置時,自動釋放池就會被釋放,池中的所有對象也就被釋放。
1.? ojc-c是通過一種"referring counting"(引用計數(shù))的方式來管理內(nèi)存的,對象在開始分配內(nèi)存(alloc)的時候引用計數(shù)為一,以后每當碰到有copy,retain的時候引用計數(shù)都會加一,每當碰到release和autorelease的時候引用計數(shù)就會減一,如果此對象的計數(shù)變?yōu)榱?,就會被系統(tǒng)銷毀.
2. NSAutoreleasePool就是用來做引用計數(shù)的管理工作的,這個東西一般不用你管的.
3. autorelease和release沒什么區(qū)別,只是引用計數(shù)減一的時機不同而已,autorelease會在對象的使用真正結(jié)束的時候才做引用計數(shù)減一.
二、幾種傳值方式的區(qū)別
傳值的方式有
1、正向傳值 : A擁有B對象的指針 B對象申明一個公開的屬性 在A中對B的屬性進行傳值?
特點:簡單直觀 易于掌握
缺點:不能進行反向傳值
2、反向傳值:需要用到代理的方法
A對象擁有B對象的指針 如果需要從B對象向A對象傳值,這時就需要用到反向傳值又稱為回調(diào) ?
方法:在B對象中寫一個代理 ?再寫一個傳值的方法 id<protocol>delegate ?(這個代理此時可以理解為A對象的一個實例對象)
【self.delegate ?實現(xiàn)代理中的方法】運行到該方法時就會調(diào)用A中的方法 并將參數(shù)傳遞過去
?在A中 A遵守B的代理 ? B對象的一個實例對象 b.delegate = self?
- (void)(B中代理的方法){
在這里實現(xiàn)可以獲得B中傳過來的值并對其進行操作
}
優(yōu)點:可以實現(xiàn)回調(diào)
缺點:實現(xiàn)起來比正向傳值略顯麻煩,在聲明代理屬性時不能使用strong修飾否則會造成強強引用,造成內(nèi)存泄漏
3、block傳值
block傳值與反向傳值有相似之處 ??
A對象擁有B對象的指針 ?
在B中聲明@propoty ?block (MyBlock)?
在B中聲明一個關(guān)于MyBlock的方法?
實現(xiàn)MyBlock的方法?
A中創(chuàng)建一個B對象的實例對象 實現(xiàn) 關(guān)于MyBlock的方法 ?
優(yōu)點:同樣可以實現(xiàn)回調(diào)
缺點:block方法靈活多變 不利于實現(xiàn) ?在block代碼塊中 self需要用weak修飾?
4、KVO觀察者模式?