Cocos2d-x使用引用计数机制实现了智能内存管理技术。
Cocos2d-x中的所有类均继承自CCObject,该类具有一个名为m_uReference的整形成员变量,记录了实例被引用的次数。
retain()方法使m_uReference+1
release()方法使m_uReference-1
当计数器减到0时release方法会通过delete this来销毁自己。
如果想让Cocos2d-x帮你管理内存,就要调用autorelease(),该方法也来自CCObject
其作用是将对象放入自动回收池(CCAutoreleasePool)。
所有使用create方法创建的Cocos2d-x对象都会在create方法中调用autorelease()。
当调用autorelease()后,对象会被添加到全局唯一的CCPoolManager对象所管理的CCAutoreleasePool对象栈的最上层的CCAutoreleasePool对象中,每一帧循环,最上层的CCAutoreleasePool对象都会被clear一次,清除它包含的所有元素,并调用一次这些元素的release方法。这保证了只有第一次被添加进CCAutoreleasePool的元素会被release一次。如果一个Cocos2d-x对象仅仅是被create实例化,没有调用过retain,则经过第一帧时,引用计数会降至0,从而被删除。
Cocos2d-x的对象在引用其他对象时,会自动retain一次。如CCArray,它在addChild时会retain被添加的对象,在removeChild时,又会release一次。或者在析构自身的时候,会将自身包含的所有元素release一遍。配合这一点,Coco2d-x的智能内存管理变得容易使用。
跟踪程序运行后,可以看到整个内存管理的实现流程如下:
CCDirector在创建的时候,init方法的第一行是setDefaultValues方法,该方法的第一行是
CCConfiguration *conf = CCConfiguration::sharedConfiguration();
sharedConfiguration()会创建一个CCConfiguration单例(因为此时是第一次)
在CCConfiguration::init的第一行,是这句
m_pValueDict = CCDictionary::create();
将会调用autorelease();此时会访问CCPoolManager::sharedPoolManager();
就创建了单例CCPoolManager
然后会调用CCPoolManager::addObject
CCPoolManager::addObject会调用
getCurReleasePool()->addObject(pObject);
getCurReleasePool()由于是第一次调用,会push()一次
而这次push()就创建了第一个CCAutoReleasePool
CCDirector在init方法的最后又push了一次,大概第二次push 的CCAutoReleasePool是作为用户使用的。因此在CCPoolManager::pop中,不会移除index = 0的CCAutoReleasePool。还要注意的是,每一帧只会移除一个CCAutoReleasePool,因为只会pop一次
关于pop,是由CCDisplayLinkDirector::mainLoop调用。该类定义与CCDirector.cpp 中
但这种内存管理只能做到把在create时没有被引用的对象删除。对于用于显示的对象来说,它们都会被其他类调用addChild添加到某个CCArray中,引用计数自然会增加1。因此不用手动调用retain和release。但是如果使用类似CCArray这样的为了保存数据而非用于显示的对象时,则需要手动retain和release,与new和delete的配对一样麻烦。但总的来说,Cocos2d-x较好地实现了游戏中最常用的显示对象的内存管理,简化了很大一部分工作。