原文連接:http://blog.sina.com.cn/s/blog_4057ab6201018y4y.htmlhtml
http://www.cnblogs.com/MobileDevelop/archive/2010/07/19/1779138.htmljava
看了上面博客中對autorelease的看法,對autorelease有了更深刻的瞭解。可是還不是很理解,因而又看了代碼。一開始對autorelease的「自動釋放」的印象老是揮之不去。老是往java那樣的徹底自動釋放那方面靠,因而第一感受就錯了。
如下僅針對 cocos2dx分析。
前言:
三種狀況,引出問題
new出來的對象須要釋放,而釋放時,若是有其餘人引用了這個對象,再次使用這個對象時,則會致使無效指針報錯。
因而有了引用計數的施放管理機制。
對於一個返回對象指針的方法。你若不看文檔不看內部代碼,你沒法知道返回的這個指針需不須要你來釋放。一樣的對於將一個指針做爲參數給一個方法後,你爲猶豫我能不能施放這個指針。由於你不知道這個方法內部會不會將你的指針施放。
因而有了誰擁有誰施放的施放管理思想。
使用了上述管理機制和思想後,有些特定狀況。好比方法內新建一個對象,而後返回對象時,按照誰擁有誰施放。對象是在方法內部新建的,方法退出前再也不擁有,因此要在方法退出前釋放。可是又要在退出時返回該對象。先返回仍是先釋放都是不對的。。。
因而就有了autorelease。
一、release 和retain是配套的,釋放管理是經過引用計數。
每個CCObject對象都有一個引用計數。retain()時引用計數+1,release()則-1.在release以後,若引用計數爲0,便會調用delete this; 真正的釋放本身的內存。
CCObject新建的時候,引用計數默認爲1.
二、release和retain的使用的指導思想是,誰擁有誰施放。
對於一個須要釋放的變量。他的生命中經過新建、傳遞參數、方法返回值出如今各類地方,然而只有有人須要長期存儲他的引用時,即想要擁有他,才應該調用retain()。釋放時則秉着「誰retain誰施放」,retain和release的調用次數要配套。
------------------------------------------------------
void class IhaveObjHandler()
{
public:
ObjX* objHandler;
static void iWantObjX(objX* o){
objHandler = o; // 位置2
objHandler->retain();
}
IhaveObjHandler(){
objHandler = NULL;
}
~IhaveObjHandler(){
if(objHandler != NULL){ objHanlder->release();}
}
}
void dispatchObjX(){
ObjX* obj = new ObjX(); // 位置1
IhaveObjHandler::iWantObjX( obj );
obj->release();
}
------------------------------------------------------
示例中:須要釋放管理的對象是 ObjX , 他在位置1新建,在位置2被傳入到IhaveObjHandler。
位置1:由於obj新建時引用計數爲1,而我(dispatchObjX方法)是不須要ObjX對象的,因此當我把他傳給IhaveObjHandler 以後,我便釋放他。
位置2:IhaveObjHandler裏須要保存
ObjX的引用,因而我(IhaveObjHandler類)調用retain()。當我不須要他,想要把他釋放的時候調用release().
在釋放的時候,注意本身retain幾回,只能釋放幾回,不能過多釋放。
三、autoreleas是一個特殊的release,即延後釋放。
對比上面的dispatchObjX方法
------------------------------------------------------
ObjX* createObjX(){
ObjX* obj = new ObjX();
obj->autorelease(); //位置3 若是改爲 obj->release();則obj的引用計數爲0,會被釋放。
return obj;
}
------------------------------------------------------
上面示例是一個產生新對象的方法。常常會用到,若是按照上述的釋放管理思想,如位置3的註釋寫的那樣。會在方法返回以前被釋放。因而有了autorelease。
autorelease其實只是爲obj設置一個標記,延後釋放。在以後的某一時刻,對obj的autorelease標記作處理(即釋放)。上面示例中autorelease不是當即減小obj引用計數,則方法能夠安全return obj;。
四、autoRelease實現原理的小細節
關鍵字CCAutoreleasePool
autorelease的對象會加入到從池中,最遲會在每一個主循環結束前釋放。
池是用棧形式管理的。在適當狀況下新建一個自動釋放池,加入到棧中。全部要釋放的對象都會加入到當前棧頂的這個池中,在特定狀況(如每次主循環結束前),將池出棧。出棧時,作一些釋放池中對象的處理。
當CCObject釋放時,若是該對象仍在自動釋放池中,則從池中刪除本身。
同一個對象屢次autorelease()的話,會被屢次加入池中。池中對象存儲結構是CCMutableArray,也就是vector.
五、 使用autorelease的好處
一、new出來的對象的釋放問題解決了。符合誰擁有誰釋放的原則。
二、能夠避免頻繁申請/釋放內存
//ttun注:(沒想出來,是什麼意思
)
六、其實autorelease並無那麼好用
綜上,autorelease只不過解決了前言中及第三條說的引用計數的那個使用上的問題。對於引用計數本質沒有太大改變。
咱們依舊要很
當心當心當心的注意釋放對象的引用計數的變化。若是引用計數亂了一個的話,會致使報錯。並且一旦因引用報錯後,通常狀況你是沒法當即知道是哪裏的引用除了問題。
另外,
使用了引用計數的話,釋放對象時別用delete, 而使用release()。