当前位置 : 主页 > 手机开发 > 其它 >

Cocos2d-x 内存管理机制

来源:互联网 收集:自由互联 发布时间:2021-06-13
Cocos2d-x 内存管理机制 By Scarb Scarb’s Blog 对Cocos2d-x的内存管理机制,之前一直不是很清楚。现在算是清楚多了,记一下笔记。 Cocos2d-x 内存管理机制 引用计数 用autorelease方法声明一个智

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. 参考资料

  1. 《我所理解的Cocos2d-x》——秦春林
网友评论