cocos2d-x 源码分析 : Ref (CCObject) 源码分析 cocos2d-x内存管理策略
来源:互联网 发布:linux c书籍 编辑:程序博客网 时间:2024/05/16 16:10
1.Ref,AutoreleasePool,PoolManager
Ref中包含了一个叫referenceCount的引用计数,当一个Ref类的变量被new的时候,其referenceCount的引用计数被置为1。 其中有三个重要的操作,retain,release,autorelease,下面源码分析时会详细说明。
AutoreleasePool中存放在被显示调用autorealse的ref,并且在每一帧过后调用其clear函数,显示的调用存放在其中的ref的realse函数,然后清空自身。
PoolManager则管理着所欲的AutoreleasePool,没有错,不仅仅有一个AutoreleasePool,有多个AutoreleasePool。
2.源码分析
如果你想清晰的了解cocos2d-x 3.x 的内存管理机制,请你一定要耐心阅读完这里的代码,源代码本身清晰易懂,何况我已经加了一些必要的中文注释呢~
2.1 Ref源码分析
重要的成员变量:_referenceCount,在构造函数中被置为1,切记。
- void Ref::retain()
- {
- CCASSERT(_referenceCount > 0, "reference count should greater than 0");
- ++_referenceCount;
- }
- Ref* Ref::autorelease()
- {
- PoolManager::getInstance()->getCurrentPool()->addObject(this);
- return this;
- }
- void Ref::release()
- {
- CCASSERT(_referenceCount > 0, "reference count should greater than 0");
- --_referenceCount;
- if (_referenceCount == 0)
- {
- delete this;
- }
- }
其中一些Debug或者追踪memory leak 的宏和函数我已经去掉,其实这三个函数的本质就是这么简单,retain和release分别增加和减少referenceCount,并且release函数在count为0时就delete 自己。autorelease函数将Ref放入当前的AutorealsePool。
Attention Please:三个函数内部都有一个CCASSERT,要求调用时该object的referenceCout必须是大于0的。
release或者autorealse必须和new或者retain成对出现。
这里开始讲一下基本的用法,因为我们平时需要我们管理的、使用的类一般都是继承于Node(Layer、Sprite等),看下Node的create函数吧。
在Node的create中,调用了new(Count设置为1)后,立即调用了autoRelease,将其放入AutoreleasePool中。(AutoreleasePool的源码一会再分析)
所以当你使用了create之后,请不要在使用release或者Autorelease,除非你手动了retain一次。
但是当你把一个node1加入到另一个node2的时候,你可以理解为此时node1的refereneceCount增加了一次,但是你不需要做任何额外的操作。因为当node1被remove或者即使没有remove操作,当node2析构的时候(会将他的child的count减1)。也就是说,整个引擎会自动管理referenceCount,只要你不要手动的retain。
2.2AutoreleasePool 源码分析
- void AutoreleasePool::clear()
- {
- #if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
- _isClearing = true;
- #endif
- for (const auto &obj : _managedObjectArray)
- {
- obj->release();
- }
- _managedObjectArray.clear();
- #if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
- _isClearing = false;
- #endif
- }
AutoRealse的clear函数十分清晰,就是调用其包含的ref的release函数,然后将自己的managedObject清空。这里需要解决的疑惑是何时调用了clear函数。打开Director的源码
- void DisplayLinkDirector::mainLoop()
- {
- if (_purgeDirectorInNextLoop)
- {
- _purgeDirectorInNextLoop = false;
- purgeDirector();
- }
- else if (! _invalid)
- {
- drawScene();
- // release the objects
- PoolManager::getInstance()->getCurrentPool()->clear();
- }
- }
在你的App运行时,每一帧开始时都是先drawScene(),各种界面上的显示结束后,就开始clear了。
2.3 PoolManager
std::deque<AutoreleasePool*> _releasePoolStack;
AutoreleasePool *_curReleasePool;
AutoreleasePool *_curReleasePool;
PoolManager管理着所有的autorerealsePool,并且有一个指针指向当前的releasePool。
值得注意的是,笔者认为3.x此处有个小bug。
- PoolManager* PoolManager::getInstance()
- {
- if (s_singleInstance == nullptr)
- {
- s_singleInstance = new PoolManager();
- // Add the first auto release pool
- s_singleInstance->_curReleasePool = new AutoreleasePool("cocos2d autorelease pool");
- s_singleInstance->_releasePoolStack.push_back(s_singleInstance->_curReleasePool);
- }
- return s_singleInstance;
- }
poolManager是单例模式,当第一次初始化的时候,会自动生成一个AutoreleasePool,并将其放入自己的stack中。但是,当你打开AutoreleasePool的构造函数时,发现其中已经有一个调用PoolManager::getInstance()->push(this); 通过debug跟踪,笔者发现此时有两个AutoRealsePool。即poolManager的stack内有两个位置都指向同一个AutoRealsePool。感觉此处应该是一个Bug。
3. 小结
1.Ref,AutorealsePool,PoolManager是紧密相关的
2.Ref的retain、new 应该与 release或者autoRealse成对出现。
3.Node的使用方式。
0 0
- cocos2d-x 源码分析 : Ref (CCObject) 源码分析 cocos2d-x内存管理策略
- cocos2d-x 源码分析 : Ref (CCObject) 源码分析 cocos2d-x内存管理策略
- cocos2d-x 源码分析 : Ref (CCObject) 源码分析 cocos2d-x内存管理策略
- cocos2d-x 源码分析 : Ref (CCObject) 源码分析 cocos2d-x内存管理策略
- 【Cocos2d-x源码分析】 Cocos2d-x内存管理解析
- cocos2d-x 源码分析
- cocos2d-x 源码分析
- cocos2d-x源码分析::内存管理机制
- cocos2d-x源码分析-CCScheduler
- cocos2d-x CCScrollView 源码分析
- cocos2d-x CCScrollView 源码分析
- 【Cocos2d-x 3.x】内存管理机制与源码分析
- cocos2d-x(2.x) CCApplication源码分析
- cocos2d-x V3.x内存管理分析
- cocos2d-x V3.x内存管理分析
- Cocos2d-x V3.x内存管理分析
- Cocos2d-x 源码分析 : Scheduler(定时器) 源码分析
- Cocos2d-x 源码分析 : Scheduler(定时器) 源码分析
- 小米口碑营销的五大秘诀
- Cannot reduce the visibility of the inherited method from 编译错误
- android 图片音乐下载
- iOS/iPhone 程序文件目录结构以及启动流程
- iosk开发结构
- cocos2d-x 源码分析 : Ref (CCObject) 源码分析 cocos2d-x内存管理策略
- 内存抖动
- 安卓文件IO部分,东抄西抄来的
- Ardunio mpu6050 dmp 数据通过串口实现与matlab(mac)实时绘图 学习过程 【2014-9-7】
- 指针的引用——在函数中的巧妙应用
- 安卓Tab导航的两种方式
- 关于mindmanager报错的解决方案
- Fedora 20升级内核后VirtualBox不能正常使用的问题
- How I Met Your Mother