Cocos2d-x 内存管理与数据结构

原创 2017年01月21日 21:33:21

Cocos2d-x 内存管理与数据结构

引用计数

Cocos采用的是引用计数的方式管理内存,Cocos会记录堆上每个对象被引用的次数,当引用次数为0时则自动释放内存。

 

Ref

为了实现对类引用次数的管理,Cocos的类都继承了Ref类。

class CC_DLLRef
{
public:
    voidretain();  //增加引用计数,当需要保存使用对象时,需要调用该函数增加引用计数
    voidrelease(); //减少引用计数,当引用计数减少到0时则时会释放内存
    Ref*autorelease(); //将内存加入自动释放内存池,下一次Application::run()的循环会调用一次对象的Release函数
    unsignedintgetReferenceCount() const;//获取引用次数
    virtual~Ref();  //虚析构函数保证派生类的析构函数被调用到
protected:
    Ref();//将构造函数设为保护属性,就无法直接实例化Ref类,new Ref()将报错
protected:
    unsignedint_referenceCount;//记录引用的次数
    friendclassAutoreleasePool;
};



AutoreleasePool

为了实现内存的自动释放AutoreleasePool创建了内存池,内存池会记录所有要自动释放的内存。

class CC_DLLAutoreleasePool
{
public:
    AutoreleasePool();
    AutoreleasePool(conststd::string&name);
    ~AutoreleasePool();
    void addObject(Ref *object);//将对象加入到自动管理内存池
    voidclear(); //清理内存
    boolcontains(Ref* object)const;//对象是否在内存池中
    voiddump(); //将内存池中的内对象信息输出到日子,方便调试
    
private:
    std::vector<Ref*>_managedObjectArray;
    std::string_name;
    
};

AutoreleasePool内存的释放

Main函数调用的Run函数的循环调用了director->mainLoop(),其每次绘制完后会清理内存

void DisplayLinkDirector::mainLoop()
{
    if(_purgeDirectorInNextLoop){
        _purgeDirectorInNextLoop= false;
        purgeDirector();
    }
    elseif(_restartDirectorInNextLoop){
        _restartDirectorInNextLoop= false;
        restartDirector();
    }
    elseif(! _invalid)
    {
        drawScene();
        //清理内存,对AutoreleasePool中的每个对象掉Ref::release函数
        PoolManager::getInstance()->getCurrentPool()->clear();
    }
}


 

引用内存的使用

new一个对象后引用计数为1,然后调用Ref::autorelease加入到自动管理内存池,对象会在下一次主循环时调用Ref::release如果需要保存对象一直使用则需要调用一次Ref::retain函数增加引用计数。例如:

//内部会调用 autorelease函数,create函数见下方代码
auto sprite = Sprite::create("HelloWorld.png"); 
this->addChild(sprite, 0);//内部会调用Ref::retain函数增加引用计数

Sprite* Sprite::create(const std::string& filename)
{
    Sprite *sprite = new (std::nothrow) Sprite();
    if (sprite && sprite->initWithFile(filename))
    {
        sprite->autorelease();
        return sprite;
    }
    CC_SAFE_DELETE(sprite);
    return nullptr;
}

 

         为了方便和统一create的定义函数,Cocos提供了相CREATE_FUNC宏,在类中加入该宏及定义了create函数。

#defineCREATE_FUNC(__TYPE__) \
static__TYPE__* create() \
{\
    __TYPE__ *pRet = new(std::nothrow)__TYPE__(); \
    if (pRet&& pRet->init()) \
    { \
        pRet->autorelease();\
        returnpRet; \
    } \
    else \
    { \
        deletepRet; \
        pRet = nullptr;\
        returnnullptr;\
    } \
}


         例如:

classHelloWorld: public cocos2d::Layer
{
public:
    virtual boolinit();
    void menuCloseCallback(cocos2d::Ref*pSender);
    //定义静态create函数
    CREATE_FUNC(HelloWorld)
};
    auto layer= HelloWorld::create();//CREATE_FUNC宏定义的函数
    scene->addChild(layer);

 

 

 

Vector

CocosVector类是对C++ STL中的std::vector进行了一层封装,其只有一个变量    std::vector<T>_data;之所以要重新封装一层,是为了实现对引用计数内存的管理。

当向_data数组中添加数据时其会对调用对象的Ref:: retain函数增加引用计数,从_data中删除数据时会调用Ref::release函数减少引用计数释放释放内存。

 

例如pushback函数和popBack函数

    voidpushBack(T object)
    {
        CCASSERT(object != nullptr,"The object should not be nullptr");
        _data.push_back( object );
        object->retain();//增加引用计数
    }
    voidpopBack()
    {
        CCASSERT(!_data.empty(), "no objects added");
        autolast= _data.back();
        _data.pop_back();
        last->release();//减少引用计数释放内存
    }

 

Map

cocos2d::Map类是使用std::unordered_map作为底层结构的关联式容器。在关联式容器的基础上进行封装实现对引用计数内存的自动管理。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Cocos2d-x 寻路算法之一 距离优先

1.效果图 寻路这块在游戏中一直很重要,花了点时间研究了下这个问题,主要参考的是《Data Structures For Game Programmers》,其他的算法用普通Console演示就行...
  • fox64194167
  • fox64194167
  • 2013年12月05日 09:06
  • 2159

cocos2d-x 中的数据结构集合(容器)(CCArray,Map,Vector)使用笔记

第1部分、CCArray cocos2d::CCArray(在3.0中已经过时,将被vector替代)是一个可变数组集合容器,放在其中的元素是有序的,并且可以重复,可以通过索引来获得元素,可以对容器内...
  • windvally
  • windvally
  • 2015年08月11日 16:14
  • 779

cocos2d-x安装与配置

最近需要用到cocos2d-x环境,便想着在我这台比较破的电脑上安装。安装过程真的是一波三折。在网上找的教程都是比较老的了,心想也没办法了,就按照这个先这么装吧!于是我就先下了coco2d-x-3.1...
  • chinalzn
  • chinalzn
  • 2017年05月12日 14:58
  • 585

Cocos2d-x 3.0新的数据结构

原文:http://hielvis.com/2014/03/30/cocos2d-x-3-0-data-structure/ 基础数据结构在游戏开发中至关重要,可能每一帧某个逻辑需要从一...
  • vinrex
  • vinrex
  • 2014年10月16日 10:06
  • 23

COCOS2D-X 3.0新的数据结构

基础数据结构在游戏开发中至关重要,可能每一帧某个逻辑需要从一个数组中查找,删除,添加数据,或者从一个字典中快速存/取一个值,游戏引擎本身也要对UI树进行遍历,排序等操作。基础数据的操作速度影响着程序的...
  • u014493178
  • u014493178
  • 2014年10月13日 14:43
  • 1250

Cocos2d-x实现计时器与定时器功能

笔者最近在写一个计时和定时的功能,上网查看了不少讲述实现计时器定时器的文章,大多都直接采用Cocos2d-x的定时器schedule。但是schedule定时器会有一定的误差。 为了尽量的消除误差,笔...
  • wsr270591269
  • wsr270591269
  • 2017年05月29日 12:10
  • 406

《Cocos2d-x实战 C++卷》上线了-源码-样章-感谢大家的支持

《Cocos2d-x实战 C++卷》上线了感谢大家一直以来的支持! 全面介绍Cocos开发技巧,采用Cocos2d-x3.2版本,并且详细介绍跨平台移植已经多平台发布细节。· 各大商店均开始销售:京东...
  • tonny_guan
  • tonny_guan
  • 2014年12月01日 21:05
  • 5005

Cocos2d-x教程(17)-Box2D 物理引擎

Box2D的基本使用方法
  • u012945598
  • u012945598
  • 2014年01月03日 13:30
  • 7676

cocos2d-x中的碰撞检测

今天在csdn看到一篇文章,写矩形与圆形的碰撞检测,借鉴了作者的检测思路,我把它用到了cocos2d-x中。 原文章的地址:http://blog.csdn.net/yorhomwang/articl...
  • guochuanqi
  • guochuanqi
  • 2014年01月16日 11:46
  • 2547

我所理解的Cocos2d-x Cocos2d-x 内存管理机制

C++内存管理C++显式堆内存管理性能上有一定优势,但有如下缺点: 野指针:指针指向的内容已经被释放,但是其他指针还可能指向它。 重复释放:重复释放一个已经释放的内存单元,或者释放一个野指针,都会导致...
  • sinat_24229853
  • sinat_24229853
  • 2016年07月21日 15:15
  • 386
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Cocos2d-x 内存管理与数据结构
举报原因:
原因补充:

(最多只允许输入30个字)