cocos2d-x学习之自动内存管理
一.自动内存管理
1)概述
C++语言默认是没有提供自动内存管理的。使用者需要自己分配,自己释放。在cocos2d-x里提供了一个自动内存管理的方案。主要是通过CCObject来提供的,用户只要继承了CCObject,就可以通过调用autorelease()来告诉系统进行自动内存管理。
一般用法就是: CCLayer* pLayer = CreateLayer(s_nActionIdx); pLayer->autorelease();
2)自动内存管理的实现
自动内存管理的实现原理大概是:用户设置自动释放功能时,内存管理(CCPoolManager)会自动把这个CCObject对象加入其管理池中。等到一定时机(场景销毁,一帧渲染结束,程序退出等),内存管理会遍历其所管理的每一个对象,逐个调用CCObject的释放函数进行释放。CCObject自己内部设置一个引用系数,增加一个使用就系数加一,释放就系数减一,当系数为0时,才真正进行释放。
如果研究下CCPoolManager,会发现进行真正内存管理的是自动释放池(CCAutoreleasePool),CCPoolManager下面包含有多个CCAutoreleasePool。CCAutoreleasePool提供了addObject,removeObject,clear功能。我开始很疑惑,因为进行内存释放管理,一个CCAutoreleasePool就够了。后来仔细考虑,发现了这个的秘密所在:
CCPoolManager管理多个CCAutoreleasePool,是为了方便确定哪个自动释放池(CCAutoreleasePool)可以进行释放,而不用影响到其他的自动释放池。比如在关卡切换时,上一个关卡的自动释放池的数据就可以进行自动释放了,而新关卡的自动释放池不变~~ 好想法!
二、引用计数器——手动管理内存
- //引用次数+1
- virtual void CCObject::retain(void);
- //引用次数-1;若引用计数器=0,则delete this;
- virtual void CCObject::release(void);
- //helper方法,快速判断当前对象只有唯一引用
- bool CCObject::isSingleRefrence(void);
- //返回引用次数
- unsigned int CCObject::retainCount(void);
- CCObject *obj=new CCObject;
- ...
- obj->release();
- obj->retain();
- ...
- obj->release();
- void CCNode::setGrid(CCGridBase* pGrid)
- {
- CC_SAFE_RETAIN(pGrid);
- CC_SAFE_RELEASE(m_pGrid);
- m_pGrid = pGrid;
- }
- CCObject* CCObject::autorelease(void);
- CCObject *obj=new CCOjbect;
- obj->autorelease();
- ...
- virtual void addChild(CCNode * child);
- virtual void addChild(CCNode * child, int zOrder);
- virtual void addChild(CCNode * child, int zOrder, int tag);
- virtual void removeChild(CCNode* child, bool cleanup);
- void removeChildByTag(int tag, bool cleanup);
- virtual void removeAllChildrenWithCleanup(bool cleanup);
- static CCSprite* spriteWithTexture(CCTexture2D *pTexture);
- static CCSprite* spriteWithTexture(CCTexture2D *pTexture, const CCRect& rect);
- static CCSprite* spriteWithTexture(CCTexture2D *pTexture, const CCRect& rect, const CCPoint& offset);
- static CCSprite* spriteWithSpriteFrame(CCSpriteFrame *pSpriteFrame);
- static CCSprite* spriteWithSpriteFrameName(const char *pszSpriteFrameName);
- static CCSprite* spriteWithFile(const char *pszFileName);
- static CCSprite* spriteWithFile(const char *pszFileName, const CCRect& rect);
- static CCSprite* spriteWithBatchNode(CCSpriteBatchNode *batchNode, const CCRect& rect);