您的位置:首页 > 移动开发 > Cocos引擎

Cocos2d-x 内存管理机制

2017-05-01 22:09 302 查看

Cocos2d-x 内存管理机制

By Scarb

Scarb’s Blog

对Cocos2d-x的内存管理机制,之前一直不是很清楚。现在算是清楚多了,记一下笔记。

Cocos2d-x 内存管理机制
引用计数

用autorelease方法声明一个智能指针

参考资料

1. 引用计数

Cocos2d-x 所有对象几乎都继承自Ref基类,该基类主要进行引用计数管理。

public:
void retain();
void release();
Ref* autorelease();
unsigned int getReferenceCount() const;

protected:
Ref();

protected:
/// count of references
unsigned int _referenceCount;
friend class AutoreleasePool;


当一个对象由
new
分配内存时,引用计数为1,调用
retain()
会增加引用计数,调用
release()
减少引用计数。

release()
方法会在引用计数为0时调用delete删除对象并释放内存。

retain()
方法在默认的
create()
函数中被自动调用。

在仅有引用计数的情况下管理UI元素的示例:

auto node = new Node();             // 引用计数为1
addChild(node);                     // 引用计数为2
// .......
node->removeFromParent();           // 引用计数为1
node->release();                    // 引用计数为0,对象被删除


此时,如果忘记调用
release()
方法就会导致内存泄露

2. 用autorelease()方法声明一个“智能指针”

Cocos2d-x 使用
autorelease()
方法来声明一个对象的指针为智能指针。

这些智能指针全部被加入一个
AutoreleasePool
中,在每一帧结束的时候对加入
AutoreleasePool
中的对象进行清理。

也就是说一个智能指针的生命周期是从被创建开始,到当前帧结束时结束。

Ref* Ref::autorelease()
{
PoolManager::getInstance()->getCurrentPool()->addObject(this);
return this;
}


在以上方法中,Cocos2d-x通过
autorelease()
方法将一个对象添加到
AutoreleasePool
中。

并在每一帧结束的时候清理当前
AutoreleasePool
中的对象:

void DisplayLinkDirector::mainLoop()
{
if(! _invalid)
{
drawScene();

// release the object
PoolManager::getInstance()->getCurrentPool()->clear();
}
}

void AutoreleasePool::clear()
{
for(const auto &obj : _manageedObjectArray)
{
obj->release();
}
_manageObjectArray.clear();
}


AutoreleasePool
对池中的每个对象执行一次
release()
操作,假设该对象的引用计数为1,表示其从未被使用,则执行
release()
操作之后引用计数为0,对象将被释放。

创建一个不被使用的
Node
如下:

auto node = new Node();             // 引用计数为1
node->autorelease();                // 加入智能指针池


该帧结束的时候
Node
对象将被自动释放。

如果在释放之前被使用

auto node = new Node();             // 引用计数为1
node->autorelease();                // 加入智能指针池
addChild(node); // 引用计数为2


该帧结束后
AutoreleasePool
对其进行1次
release()
操作之后,引用计数为1,该对象继续存在。

当下次该
Node
被移除的时候,引用计数为0,对象被自动释放。

此时该
AutoreleasePool
中的所有对象已经被移出,没有被释放的对象引用为1,继续存在。当
remove
该对象或者该对象的父节点被
remove
时,都会
release
该对象。


Cocos2d-x 使用静态的
create()
方法返回一个智能指针对象。同时自定义的UI元素也应该遵循这样的风格。

Node* Node::create()
{
Node *ret = new Node();
if (ret && ret->init())
{
ret->autorelease();
}
else
{
CC_SAFE_DELETE(ret);
}
return ret;
}


3. 参考资料

《我所理解的Cocos2d-x》——秦春林
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: