上一节说到的Ref的引用计数时,没有说自动释放。
自动释放功能相对来说比较复杂。
首先有一个自动释放池。
#ifndef __autoRELEASEPOol_H__#define __autoRELEASEPOol_H__#include <string>#include <vector>#include "Ref.h"class autoreleasePool { public: autoreleasePool(); autoreleasePool(const std::string &name); ~autoreleasePool(); voID addobject(Ref *object); voID clear(); bool contains(Ref* object) const; private: std::vector<Ref*> _managedobjectArray;// 对象数组,存放自动释放的对象 std::string _name;// 释放池名字};class PoolManager { public: static PoolManager* getInstance(); static voID destroyInstance(); autoreleasePool *getCurrentPool() const; bool isObjectInPools(Ref* obj) const; frIEnd class autoreleasePool; private: PoolManager(); ~PoolManager(); voID push(autoreleasePool *pool); voID pop(); static PoolManager* s_singleInstance; std::vector<autoreleasePool*> _releasePoolStack;};autoreleasePool::autoreleasePool(): _name("") { _managedobjectArray.reserve(150); PoolManager::getInstance()->push(this);}autoreleasePool::autoreleasePool(const std::string &name): _name(name) { _managedobjectArray.reserve(150); PoolManager::getInstance()->push(this);}autoreleasePool::~autoreleasePool() { clear(); PoolManager::getInstance()->pop();}voID autoreleasePool::clear() { // 与一个默认大小的vector交换,使其恢复到默认大小 // 再释放临时的vector对象,已达到释放内存,恢复到默认大小的目的 std::vector<Ref*> releasings; releasings.swap(_managedobjectArray); std::vector<Ref*>::iterator it = releasings.begin(); for (; it != releasings.end(); it++) { (*it)->release(); }}bool autoreleasePool::contains(Ref* object) const { std::vector<Ref*>::const_iterator it = _managedobjectArray.begin(); for (; it != _managedobjectArray.end(); it++) { if(object == (*it)) { return true; } } return false;}voID autoreleasePool::addobject(Ref* object) { _managedobjectArray.push_back(object);}/* * PoolManager * */PoolManager* PoolManager::s_singleInstance = NulL;PoolManager* PoolManager::getInstance() { if (NulL == s_singleInstance) { s_singleInstance = new PoolManager(); // 创建单例的后悔初始化自动释放池 new autoreleasePool("cocos2d autorelease pool"); } return s_singleInstance;}voID PoolManager::destroyInstance() { delete s_singleInstance; s_singleInstance = NulL;}PoolManager::PoolManager() { _releasePoolStack.reserve(10);}PoolManager::~PoolManager() { while (!_releasePoolStack.empty()) { autoreleasePool* pool = _releasePoolStack.back(); delete pool; }}autoreleasePool* PoolManager::getCurrentPool() const { return _releasePoolStack.back();}bool PoolManager::isObjectInPools(Ref* obj) const { std::vector<autoreleasePool*>::const_iterator it = _releasePoolStack.begin(); for (;it != _releasePoolStack.end(); ++it) { if ((*it)->contains(obj)) { return true; } } return false;}voID PoolManager::push(autoreleasePool *pool) { _releasePoolStack.push_back(pool);}voID PoolManager::pop() { if (!_releasePoolStack.empty()) { _releasePoolStack.pop_back(); }}#endif
当我们调用Ref对象的autorelease方法时,就会当该对象加入到自动释放池中。
Ref* Ref::autorelease(){ PoolManager::getInstance()->getCurrentPool()->addobject(this); return this;}
另外,还有一个自动释放池对象PoolManager,专门来管理自动释放池。
自动释放管理对象是一个单例,但我们第一次获取这个单例的时候,就会创建一个自动释放池。
PoolManager* PoolManager::getInstance() { if (NulL == s_singleInstance) { s_singleInstance = new PoolManager(); // 创建单例的后初始化自动释放池 new autoreleasePool("cocos2d autorelease pool"); } return s_singleInstance;}
然后在Director的mainLoop中,每一帧都会检测自动释放池,release对象,释放引用计数为0的对象。
voID displaylinkDirector::mainLoop() { drawScene(); // 每一帧都会检测自动释放池 PoolManager::getInstance()->getCurrentPool()->clear();}
代码 总结
以上是内存溢出为你收集整理的自己动手写cocos2dx游戏引擎(七)——自动释放池全部内容,希望文章能够帮你解决自己动手写cocos2dx游戏引擎(七)——自动释放池所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)