一、引用计数
基类Ref的作用就是通过引用计数来管理对象的生命周期,引用计数规则:
- 引用计数
- _referenceCount,初始为1。
 
 - retain()
- _referenceCount加1。
 
 - release()
- _referenceCount减1,如果此时为0了,删除对象。
 
 
cocos几乎所有对象都继承自Ref。
下面是Ref中引用计数相关的源码。
class CC_DLL Ref{public:void retain(); // _referenceCount + 1void release(); // _referenceCount - 1Ref* autorelease(); // 加入当前的autoReleasePoolunsigned int getReferenceCount() const; // 当前的引用计数protected:Ref(); // _referenceCount初始为1protected:unsigned int _referenceCount; // 当前这个对象的引用计数......};Ref::Ref(): _referenceCount(1){}void Ref::retain(){++_referenceCount;}void Ref::release(){--_referenceCount;if (_referenceCount == 0){delete this;}}unsigned int Ref::getReferenceCount() const{return _referenceCount;}Ref* Ref::autorelease() //加入到当前的Pool中,见下面{PoolManager::getInstance()->getCurrentPool()->addObject(this);return this;}
二、自动化管理
我们已经能够管理cocos对象的生命周期,但是很麻烦,必须手动retain、release,我们可以借助渲染循环作为作为“驱动力”,来实现自动化。
cocos用一个AutoReleasePool来管理需要auto relase的Ref对象,用一个栈结构来保存pool,在帧结尾处,当前pool(栈顶pool)的所有对象release一次。
void Director::mainLoop(){......;drawScene();......PoolManager::getInstance()->getCurrentPool()->clear(); // release the objects......}
使用方法示例如下:
void fuck(){// 在构造时候,poolManager将pool压栈 即成为current pool// pool在析构时,pool中所有Ref对象都将release一次,并弹栈AutoReleasePool pool;Node *pNode1 = Node::create(); // 加入current poolNode *pNode2 = Node::create(); // 加入current poolRef *pRef = new Ref();pRef->autorelease(); // 加入current poolDirector::getInstnace()->getRunningScene()->addChild(pNode1);}// 函数结束,触发pool的析构,上面所有Ref对象都release一次,// release之后,引用计数情况如下:// pNode1->release之后,引用计数=1,当runningScene->removeChild(pNode1)时,pNode1将被delete// pNode2->release之后,引用计数=0,立即被delete// pRef->release之后,引用计数=0,立即被delete
AutoreleasePool
自动回收池,存储要进行AutoRelease的Ref对象。
std::vector<Ref*> _managedObjectArray; // 存储要autoRelease的对象AutoreleasePool::AutoreleasePool(){// 预计管理的对象数量不会超过150个。_managedObjectArray.reserve(150);PoolManager::getInstance()->push(this); //设置为当前的AutoreleasePool}AutoreleasePool::~AutoreleasePool(){ //清空池,所有对象releaseclear();PoolManager::getInstance()->pop(); //当前AutoreleasePool改为上一个}void AutoreleasePool::addObject(Ref* object){ //对象加入AutoreleasePool_managedObjectArray.push_back(object);}void AutoreleasePool::clear(){ //清空池,所有对象releasestd::vector<Ref*> releasings;releasings.swap(_managedObjectArray);for (const auto &obj : releasings){obj->release();}}
PoolManager
通过一个栈来管理AutoreleasePool,需要自动回收的对象都将被添加到栈顶的Pool中,即当前的Pool。
栈底初始有一个常驻的Pool。
部分源码如下:
// 栈结构,保存auto release pool,栈顶pool为当前poolstd::vector<AutoreleasePool*> _releasePoolStack;PoolManager* PoolManager::getInstance(){if (s_singleInstance == nullptr){s_singleInstance = new (std::nothrow) PoolManager();new AutoreleasePool("cocos2d autorelease pool"); // 栈底初始就有一个Pool}return s_singleInstance;}PoolManager::PoolManager(){_releasePoolStack.reserve(10); // Pool最好限制在10个以内。}AutoreleasePool* PoolManager::getCurrentPool() const { // 栈顶Poolreturn _releasePoolStack.back();}void PoolManager::push(AutoreleasePool *pool){_releasePoolStack.push_back(pool);}void PoolManager::pop(){_releasePoolStack.pop_back();}
