cocos2d-x 3.0 内存管理机制

Posted gcczhongduan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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********************************************





























以上是关于cocos2d-x 3.0 内存管理机制的主要内容,如果未能解决你的问题,请参考以下文章

Cocos2d-x 3.0 屏幕触摸及消息分发机制

Cocos2d-X研究之3.0 场景切换特效汇总

13Cocos2dx 3.0游戏开发找小三之3.0中的Director :郝萌主,一统江湖

关于cocos2d-x 3.0的点击交互处理

Cocos2d-x 3.0多线程异步资源载入代码

Cocos2d-x 3.0final 终结者系列教程02-开发环境的搭建