標籤:cocos2d-x 3.0 記憶體管理機制 淺析入門
***************************************轉載請註明出處:http://blog.csdn.net/lttree********************************************
再來一彈,記憶體管理機制
1.簡言機制
2.代碼觀機制
1.簡言-Cocos2d-x的記憶體管理機制
說到記憶體管理,這是個question,(⊙v⊙)嗯。。
看一下各語言怎麼進行記憶體管理吧?
——JAVA:
堆區的就是new來分配記憶體,通過記憶體回收機制來回收。
(具體的很複雜,可以看看這個文章 -> http://blog.csdn.net/tutngfei1129287460/article/details/7383480 )
——C++:
new來建立,delete來刪除
——Objective-C:
採用引用計數的方法
建立一個Obj,每個Obj都有一個retainCount,
在new、alloc、retain的時候,都會讓這個retainCount+1;
若對這個對象,進行release操作,則會讓retainCount-1。
所以,每個對象都有兩個方法:retain和release。
當retainCount為0時,這個對象就被釋放了。
而Cocos2d-x 使用C++實現了Objective-C的管理機制。
2.代碼觀-cocos2d-x的記憶體管理機制
建立一個對象,來看看一看這個管理機制。
開啟項目,在入口程式AppDelegate.cpp中可以看到:
// create a scene. it's an autorelease objectauto scene = HelloWorld::createScene(); // run director->runWithScene(scene);
建立了一個情境,並運行,跟蹤進去,建立情境的函數:
// 'scene' is an autorelease object auto scene = Scene::create(); // 'layer' is an autorelease object auto layer = HelloWorld::create();
在createScene函數中,進行了情境的建立和圖層的建立。
都用的是create方法,無論是scene還是layer,它們都是屬於node子類,同樣node也是ref的子類。
之前說過,Ref類就是cocos2d-x的記憶體管理機制。
跟蹤到,Ref類,可以發現:
<span style="font-size:14px;">class CC_DLL Ref{public: /** * Retains the ownership. * * This increases the Ref's reference count. * * @see release, autorelease * @js NA */ void retain(); /** * Release the ownership immediately. * * This decrements the Ref's reference count. * * If the reference count reaches 0 after the descrement, this Ref is * destructed. * * @see retain, autorelease * @js NA */ void release(); /** * Release the ownership sometime soon automatically. * * This descrements the Ref's reference count at the end of current * autorelease pool block. * * If the reference count reaches 0 after the descrement, this Ref is * destructed. * * @returns The Ref itself. * * @see AutoreleasePool, retain, release * @js NA * @lua NA */ Ref* autorelease(); /** * Returns the Ref's current reference count. * * @returns The Ref's reference count. * @js NA */ unsigned int getReferenceCount() const; protected: /** * Constructor * * The Ref's reference count is 1 after construction. * @js NA */ Ref(); public: /** * @js NA * @lua NA */ virtual ~Ref(); protected: /// count of references unsigned int _referenceCount; friend class AutoreleasePool; #if CC_ENABLE_SCRIPT_BINDINGpublic: /// object id, ScriptSupport need public _ID unsigned int _ID; /// Lua reference id int _luaID;#endif};</span>
。。。。。 好長
裡面有:
retain方法(增加引用),
release方法(減少引用),
autorelease方法(實現自動釋放)
getReferenceCount方法(獲得引用計數)
Ref(),~Ref() 建構函式和解構函式
_referenceCount這個就是引用值
AutoreleasePaul友元類
_ID,_luaID對JS和Lua指令碼的支援
再看一下,這個類的具體定義,
可以在專案檔夾內的:cocos2d/cocos/base/找到Ref類
也可以在,VS2012開啟後,外部依賴項裡找Ref類,但找到的都是.h標頭檔,我們要看的.cpp喲
但是,這個類找的時候,叫CCRef
——在,Ref建構函式可以看到:
Ref::Ref(): _referenceCount(1) // when the Ref is created, the reference count of it is 1
也就是說,每當建立一個對象,它的引用值初始化為1。
——當,執行retain方法
void Ref::retain(){ CCASSERT(_referenceCount > 0, "reference count should greater than 0"); ++_referenceCount;}會對引用值++
——當,執行release方法
void Ref::release(){ CCASSERT(_referenceCount > 0, "reference count should greater than 0"); --_referenceCount;會對引用值--
——且,release後,要進行是否為0的判斷,若為0,則delete this:
if (_referenceCount == 0) {#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0) auto poolManager = PoolManager::getInstance(); if (!poolManager->getCurrentPool()->isClearing() && poolManager->isObjectInPools(this)) { CCASSERT(false, "The reference shouldn't be 0 because it is still in autorelease pool."); }#endif delete this; }
從此可見,cocos2d-x是通過引用計數來控制對象的生命週期。因此,cocos2d-x編程時,基本不用delete語句,只有在非Ref基類的類或者Ref類內才會用delete語句。
再回過頭,看一下Scene的create方法:
Scene *Scene::create(){ Scene *ret = new Scene(); if (ret && ret->init()) { ret->autorelease(); return ret; } else { CC_SAFE_DELETE(ret); return nullptr; }}在這裡面,我們先建立情境,然後執行情境初始化方法(init),然後把當前對象添加到自動釋放池管理,
這個方法定義:
Ref* Ref::autorelease(){ PoolManager::getInstance()->getCurrentPool()->addObject(this); return this;}這樣一來,我們就不需要自己明確的編碼,而且當對象被引用,自動進行release方法。
——end
恩,就到這裡了,本來想用執行個體來運行一下,可出了些問題。
明天就要走了,有段時間不能上了,唉。。
參考資料:
sdhjob(沈老師)
***************************************轉載請註明出處:http://blog.csdn.net/lttree********************************************