Cocos2d-x 内存管理机制

前端之家收集整理的这篇文章主要介绍了Cocos2d-x 内存管理机制前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Cocos2d-x 内存管理机制

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

1. 引用计数

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

  1. public:
  2. void retain();
  3. void release();
  4. Ref* autorelease();
  5. unsigned int getReferenceCount() const;
  6.  
  7. protected:
  8. Ref();
  9.  
  10. protected:
  11. /// count of references
  12. unsigned int _referenceCount;
  13. friend class AutoreleasePool;

当一个对象由new分配内存时,引用计数为1,调用retain()增加引用计数,调用release()减少引用计数。
release()方法会在引用计数为0时调用delete删除对象并释放内存。
retain()方法在默认的create()函数中被自动调用

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

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

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

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

Cocos2d-x 使用autorelease()方法来声明一个对象的指针为智能指针。
这些智能指针全部被加入一个AutoreleasePool中,在每一帧结束的时候对加入AutoreleasePool中的对象进行清理。
也就是说一个智能指针的生命周期是从被创建开始,到当前帧结束时结束。

  1. Ref* Ref::autorelease()
  2. {
  3. PoolManager::getInstance()->getCurrentPool()->addObject(this);
  4. return this;
  5. }

在以上方法中,Cocos2d-x通过autorelease()方法将一个对象添加AutoreleasePool中。
并在每一帧结束的时候清理当前AutoreleasePool中的对象:

  1. void DisplayLinkDirector::mainLoop()
  2. {
  3. if(! _invalid)
  4. {
  5. drawScene();
  6.  
  7. // release the object
  8. PoolManager::getInstance()->getCurrentPool()->clear();
  9. }
  10. }
  11.  
  12. void AutoreleasePool::clear()
  13. {
  14. for(const auto &obj : _manageedObjectArray)
  15. {
  16. obj->release();
  17. }
  18. _manageObjectArray.clear();
  19. }

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

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

该帧结束的时候Node对象将被自动释放。
如果在释放之前被使用

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

该帧结束后AutoreleasePool对其进行1次release()操作之后,引用计数为1,该对象继续存在。
当下次该Node被移除的时候,引用计数为0,对象被自动释放。

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


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

  1. Node* Node::create()
  2. {
  3. Node *ret = new Node();
  4. if (ret && ret->init())
  5. {
  6. ret->autorelease();
  7. }
  8. else
  9. {
  10. CC_SAFE_DELETE(ret);
  11. }
  12. return ret;
  13. }

3. 参考资料

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

猜你在找的Cocos2d-x相关文章