cocos2d-x採用”引用計數”的方式來管理物件的持有和釋放,所謂引用計數就是每個物件都會有一個屬性用來記錄當前被引用之次數,當要釋放記憶體的時候會根據這個引用計數來確定是否要用delete()方法來釋放這個物件佔用的記憶體。
回到正題看autoRelease()這個方法,以Java觀點來看原以為調用這個方法後物件就被加到了一個自動化記憶體管理器裡,就可如在Java裡面一樣new物件以後就可放任不管,由系統自動判斷在適當時機進行物件回收,但在C++本身實現並不能做到像Java一樣程度的自動記憶體管理,可看autoRelease() 方法的代碼內容如下:
CCPoolManager::sharedPoolManager()->addObject(this);
由代碼之意是把當前物件加到一個記憶體池物件中,再追溯根源查看CCPoolManager類,可進行分析代碼作解讀,但筆者將其採用之運作原理歸納如下:
n
當一個物件被加到CCPoolManager裡面以後這個物件的引用計數被設為1(此時未再透過retain()方法調用它的情況下),若在CCDirect類的主迴圈方法mainLoop()裡面會調用CCPoolManager類的pop()方法,pop()方法的作用其實只有一個:把當前持有的物件引用作釋放,並同時調用物件之autoRelease()方法通知CCPoolManager類(※此時物件有可能被釋放也有可能不釋放,這取決於引用計數之數值),pop()方法被調用以後,之前通過autoRelease()方法加到CCPoolManager類中之同類型物件便不再管理,因已放棄對這類物件的引用,故須知這個autoRelease()方法之作用其實只是通知CCPoolManager類所管理之物件而已,是否完全釋放物件取決於引用計數之數值而定。
上述作法是cocos2d-x記憶體管理機制之規則,當調用retain()方法或透過new生成物件必須與autoRelease()成對出現,不管在何處構造物件當調用了某個物件的retain()方法時,那麼在解構時就一定要調用該物件的autoRelease()方法告知CCPoolManager類進行管理。
一般在寫代碼時通常只是把一個Sprite加到Layer中,實際上是加入到CCNode的一個陣列中,此在加入這個陣列過程中會調用物件的retain()方法,在移除物件時會調用autoRelease()方法。同時在建構函式時Layer也會調用這個陣列的autoRelease()方法,陣列又調用它所持有物件的autoRelease()方法,此實現機制還是內部會自動以引用計數進行管控,但須注意的是,物件是否完全被釋放的問題,在寫代碼時還是要小心作判讀,以免記憶體產生溢出現象。
總結一下:autoRelease()主要是用來管理方法作用域內通過new創建物件之記憶體釋放,以達到如普通定義之物件一樣在方法調用一結束時就進行釋放。具體作法可參考CCObeject類之預設構造函數、retain()及autoRelease()方法。
※後序:記憶體管理對嵌入型裝置尤為重要,開發程式時應多注意,避免溢出現象(記憶體不足)產生。
0 意見:
張貼留言