AutoreleasePool
和PoolManager
这里PoolManager
是运用了单例模式,cocos2dx中用到了很多单例,例如Director
,SimpleAudioEngine
等等。
除此之外,PoolManager
实际是对AutoreleasePool
的一次封装。
路径
1
| base/CCAutoreleasePool.h
base/CCAutoreleasePool.cpp
|
源码分析
PoolManager
这里先贴上PoolManager
的类声明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| class CC_DLL PoolManager { public: CC_DEPRECATED_ATTRIBUTE static PoolManager* sharedPoolManager() { return getInstance(); } static PoolManager* getInstance();
CC_DEPRECATED_ATTRIBUTE static void purgePoolManager() { destroyInstance(); } 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::deque<AutoreleasePool*> _releasePoolStack;
AutoreleasePool *_curReleasePool; };
|
PoolManager
的实现相对比较简单,所以这里代码就不贴出来了。
PoolManager
实际是在维护一个双端队列,貌似就直接把这个双端队列当做栈来用了。
如果我们在cocos2dx中没有调用PoolManager
的push
和pop
的操作的话,那么整个流程就变得更加简单。
整个游戏对内存的操作大致有如下情况:
这些对象刚刚开始的时候都会被放入AutoreleasePool
中,然后马上进行一次clear
这里主要是对那些创建了,但是没有使用的对象进行清除。
渲染树节点都是Node的子类
然后加到渲染树中的时候,会调用Ref::retain
,具体见Node
若是从渲染树种删除,可以选择是否清除,这里的清除就是调用Ref::release
,具体见Node
AutoreleasePool
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| class CC_DLL AutoreleasePool { public: AutoreleasePool(); AutoreleasePool(const std::string &name);
~AutoreleasePool();
void addObject(Ref *object);
void clear();
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0) bool isClearing() const { return _isClearing; }; #endif
bool contains(Ref* object) const;
void dump();
private: std::vector<Ref*> _managedObjectArray; std::string _name;
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0) bool _isClearing; #endif };
|
上面我们也提到了clear
方法,让我们来看看具体是什么个鸟东西=。=
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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 }
|
噢~~原来只是遍历下数组,然后直接调用每个对象的Ref::release
方法,最后直接清空这个数组。
这个clear没帧都会被调用,为了清除那些创建出来,但是没有使用的对象。
至于这个每帧的调用在Director
中实现,这几天我开篇文章来分析分析=。=
总结
对于这几天写的文章,应该做一个总结,即Ref
,Node
,AutoreleasePool
和PoolManager
等类的结合分析。