cocos2d-x3.0的内存管理机制

cocos2d-x中的内存管理机制可以看成给予智能指针的一个变体,但它同时是程序员进而一项实用垃圾回收机制那样不需要声明智能指针
1,引用计数
cocos2d中所有的对象几乎都集成自Ref基类。Ref基类的主要职责就是对对象进行引用计数管理 如下

class CC_DLL Ref
{
    public:
          void retain();
          void release();
            Ref* autorelease();
            unsigned int getReferenceCount() const;
          protected:
                Ref();

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

当一个对象使用new运算符分配内存时,其引用计数为1,调用retain()方法会增加其引用计数,调用release()方法可以减少引用计数,relese()方法会在其应用技术为零时自动调用delete运算符删除对象并释放内存
除此之外retain()方法和release()方法没有做其他任何事情,他们只是帮助我们记录一个对象引用次数,时间上,在程序中很少单独使用这两个方法来管理内存。因为最重要的还是要在设计的时候就明确他们应该在那个地方被释放,大多数引用只是一种弱引用关系,使用这两个发法反而会增加复杂性
在仅有引用计数的情况下管理UI原酸 示例如下:

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

显然这不是我们想要的结果。如果忘记调用release()方法就会导致内容存泄漏
2,用autorelease()方法声明一个“智能指针”
如果讲一个动态分配的内存与一个自动变量关联,那么当这个自动变量的生命周期结束时 释放这块对内存,从而使程序员不必担心器内存无法释放。
Cocos2d-x使用autorelease()方法声明一个对象指针为智能指针,但是这些智能指针并不单独关联某个自动变量,而是全部被加入到一个AutoreleasePool中 在每一帧结束得到时候对加入AutoreleasePool中的对象进行清理
Cocos2d-x中一个智能指针的创建开始到当前帧结束示例如下:

//通过autorelease()将一个对象添加到AutoreleasePool中
Ref* Ref::autorelease()
{
  PoolManager::getInsatance()->getCurrentPool()->addObject(this);
  return this; 
}
//在每一帧结束的时候清理当前AutoreleasePool中的对象,示例如下
void DIsplayLinkDirector::mainLoop()
{
  if (! _invalid)
    {
        drawScene();
        //release the objects
  PoolManager::getInstance()->getCurrentPool()->clear();
    }
}

void AurtoreleasePool::clear()
{
  for(const auto &obj:_managedObjectArray)
{
    obj->release();
}
_managedObjectArray.clear();

}

实际上的实现机制是:AutoreleasePool对池中的每个对象执行一次release操作,假设该对象的引用计数为1表示从未被使用,则执行release操作后引用计数为零,对象江北释放。
以下创建一个不被使用的Node

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

可以预计当侦结束的时候Node将被自动释放,如果该对象在真结束之前被使用示例如下

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

在该帧结束的时候。AutoreleasePool对其执行1次release操作后引用计数为1,该对象继续存在。当下次该Node被移出的时候引用计数为零,对象就会被释放。这样就实现了Ref对象的自动内存管理。
然而,这需要程序员 手动声明其是”智能“的
示例如下

auto node = new Node ();
node->autorelease();//在cocos2d-x中声明智能指针

为了简化这种声明,ococs2d-x使用静态的create()方法来返回一个智能指针对象。cocos2d-x中大部分的类都可以通过create()方法返回一个智能指针对象 如 Node ,Action 等。同时,自定义的UI元素也应该遵循这样的风格 如下

Node * Node::cretae(void)
{
  Node *ret = new Node()
  if (ret && ret->init()
  {
    ret->autorelease();
  }
  else
  {
  CC_SAFE_DELETE(ret);
  }
  reutrn ret;
}

推荐阅读更多精彩内容