zoukankan      html  css  js  c++  java
  • 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 object
    	auto 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_BINDING
    public:
        /// 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********************************************

  • 相关阅读:
    asp.net 2.0 run
    Regular Expression
    assembly
    asp.net loading..
    session
    asp.net performance
    asp.net page order
    interface
    UVA 562 Dividing coins
    UVA 10003 Cutting Sticks
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5286574.html
Copyright © 2011-2022 走看看