cocos2d-x 3.0 記憶體管理機制

來源:互聯網
上載者:User

標籤: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********************************************

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.