cocos-js,内存管理方式
一.开篇引题在理解cocos2dx的内存管理机制之前,我们可以先了解下c++中变量的内存空间的分配问题.
问题来了,cocos2dx如何管理内存:
二.示例讲解1.c++代码示例//对象创建的时候引用计数被设置为1,这个是在它的构造函数中完成的,它会先调用父类Ref的构造函数
//Ref::Ref()
//: _referenceCount(1)
Node * node = new Node();
("retain count:%d",node->getReferenceCount());
//调用retain方法的时候引用计数增加1
node->retain();
log("retain count:%d",node->getReferenceCount());
//调用release方法的时候引用计数减1,当这个引用计数减为0的时候,在release方法中会delete掉这个对象
node->release();
log("retain count:%d",node->getReferenceCount());
//当我们调用autorelease方法的时候会调用这段代码
//PoolManager::getInstance()->getCurrentPool()->addObject(this);
//调用autorelease方法的时候对象会被放到自动回收池中,这个自动回收池在每帧结束的时候会调用一次对象的release方法
node->autorelease();
log("retain count:%d",node->getReferenceCount());
void DisplayLinkDirector::mainLoop()
{
if (_purgeDirectorInNextLoop)
{
_purgeDirectorInNextLoop = false;
purgeDirector();
}
else if (_restartDirectorInNextLoop)
{
_restartDirectorInNextLoop = false;
restartDirector();
}
else if (! _invalid)
{
drawScene();
// release the objects
PoolManager::getInstance()->getCurrentPool()->clear();
}
}
void AutoreleasePool::clear()
{
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
_isClearing = true;
#endif
std::vector<Ref*> releasings;
releasings.swap(_managedObjectArray);
for (const auto &obj : releasings)
{
obj->release();
}
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
_isClearing = false;
#endif
}
下面我们来看一下,通常我们的代码都是怎么写的,来看看这个自动回收机制怎么就做到自动回收了! //在create的时候调用了sprite的autorelease方法
CCSprite * sprite = CCSprite::create("HelloWorld.png");
CCLog("retain count:%d",sprite->getReferenceCount()); //retain 1
this->addChild(sprite);
CCLog("retain count:%d",sprite->getReferenceCount()); //retain 2
Node * Node::create()
{
Node * ret = new (std::nothrow) Node();
if (ret && ret->init())
{
ret->autorelease();
}
else
{
CC_SAFE_DELETE(ret);
}
return ret;
}
有可能有的人又会问,在new 一个node后可不可以就让它的引用计数为0,而不需要调用autorelease方法呢? 我们再来看下addChild时引用计数+1,removeChild时引用计数-1相关的代码: 在addChild方法里有一句this->insertChild(child,localZOrder);
在insertChild方法里有一句_children.pushBack(child);
最后在pushBack方法里:
void pushBack(T object)
{
CCASSERT(object != nullptr,"The object should not be nullptr");
_data.push_back( object );
object->retain();
}
2.JS代码示例我们先来看JS的模板工程代码: var HelloWorldLayer = cc.Layer.extend({
sprite:null,ctor:function () {
//////////////////////////////
// 1. super init first
this._super();
/////////////////////////////
// 2. add a menu item with "X" image,which is clicked to quit the program
// you may modify it.
// ask the window size
var size = cc.winSize;
// add a "close" icon to exit the progress. it's an autorelease object
var closeItem = new cc.MenuItemImage(
res.CloseNormal_png,res.CloseSelected_png,function () {
cc.log("wade getReferenceCount1:"+helloLabel.getReferenceCount())
cc.log("wade getReferenceCount2:"+this.sprite.getReferenceCount())
},this);
closeItem.attr({
x: size.width - 20,y: 20,anchorX: 0.5,anchorY: 0.5
});
var menu = new cc.Menu(closeItem);
menu.x = 0;
menu.y = 0;
this.addChild(menu,1);
/////////////////////////////
// 3. add your codes below...
// add a label shows "Hello World"
// create and initialize a label
// var helloLabel = new cc.LabelTTF("Hello World","Arial",38);
var helloLabel = cc.LabelTTF.create("Hello World",38);
// position the label on the center of the screen
helloLabel.x = size.width / 2;
helloLabel.y = size.height / 2 + 200;
// add the label as a child to this layer
this.addChild(helloLabel,5);
cc.log("wade getReferenceCount1:"+helloLabel.getReferenceCount())
// add "HelloWorld" splash screen"
this.sprite = new cc.Sprite(res.HelloWorld_png);
this.sprite.attr({
x: size.width / 2,y: size.height / 2
});
this.addChild(this.sprite,0);
cc.log("wade getReferenceCount2:"+this.sprite.getReferenceCount())
return true;
}
});
getReferenceCount这个方法就是获取引用计数的,在 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
