cocos2d-x 3.1.1源码阅读过程的注释
印象笔记链接:http://app.yinxiang.com/l/AAU8F1mKiN9BIqFopReAU3ZbTcgGOULycQo/
每个类的基类是Ref 也就是2.0的CCObject 调用继承下来的下面的那个函数
class CC_DLL Ref
{
public:
/**
引用计数+1
*/
void retain();
{
CCASSERT(_referenceCount
> 0, "reference count should greater than 0" );
++_referenceCount;
}
/**
引用计数-1
*/
void release();
{
CCASSERT(_referenceCount
> 0, "reference count should greater than 0" );
--_referenceCount;
if (_referenceCount
== 0)
{
#if defined (COCOS2D_DEBUG)
&& ( COCOS2D_DEBUG > 0)
auto poolManager
= PoolManager ::getInstance();
if (!poolManager->getCurrentPool()->isClearing()
&& poolManager->isObjectInPools( this))
{
// 错误实例1:
// auto obj = Node::create();
// obj->autorelease();
//create函数里面封装了 autorelease
// 错误实例2:
// auto obj = Node::create();
// obj->release(); // Wrong:
obj is an autorelease Ref, it will be released when clearing current pool.
CCASSERT(false , "The
reference shouldn‘t be 0 because it is still in autorelease pool.");
}
#endif
#if CC_USE_MEM_LEAK_DETECTION
untrackRef( this);
#endif
delete this ;
}
/**
* 自动释放 也就是当前的AutoReleasePool被调用了析构函数之后 引擎全局有一个AutoReleasePool
*/
Ref*
autorelease();
{
PoolManager::getInstance()->getCurrentPool()->addObject( this);
return this;
}
/**
* 返回引用数量
*/
unsigned int getReferenceCount() const ;
protected:
/**
* 在构造了之后引用计数是1!!!!!
*/
Ref()
: _referenceCount(1) // when the Ref is
created, the reference count of it is 1
{
#if CC_ENABLE_SCRIPT_BINDING
static unsigned int uObjectCount
= 0;
_luaID = 0;
_ID = ++uObjectCount;
#endif
#if CC_USE_MEM_LEAK_DETECTION
trackRef(this);
#endif
}
public:
virtual ~Ref();
protected:
/// count of references
unsigned int _referenceCount;
friend class AutoreleasePool ;
#if CC_ENABLE_SCRIPT_BINDING
public:
/// object id, ScriptSupport need
public _ID
unsigned int
_ID;
/// Lua reference id
int
_luaID;
#endif
#if CC_USE_MEM_LEAK_DETECTION
public:
static void printLeaks();
#endif
};
PoolManager类的解析:
class CC_DLL PoolManager
{
public:
//这个是表示这个接口以后要丢弃
CC_DEPRECATED_ATTRIBUTE static PoolManager *
sharedPoolManager() { return getInstance();
}
/**
这里也是十分重要的 整个程序只有一个单例的PoolManager PoolManager初始化的时候就添加了一个AutoreleasePool
*/
static 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;
}
CC_DEPRECATED_ATTRIBUTE static void purgePoolManager()
{ destroyInstance(); }
static void destroyInstance();
/**
* 获得现在的释放池, 引擎自己创建了一个autoreleasePool
* 你可以创建自己的释放池 会放进自动释放池的盏变量里面
*/
AutoreleasePool *getCurrentPool() const;
{
return _curReleasePool;
}
bool isObjectInPools( Ref*
obj) const ;
friend class AutoreleasePool ;
private:
PoolManager();
~PoolManager();
void push( AutoreleasePool *pool);
{
_releasePoolStack.push_back( pool);
_curReleasePool = pool;
}
void pop();
{
// 如果是弹出第一个
CC_ASSERT(_releasePoolStack.size()
>= 1);
_releasePoolStack.pop_back();
// 应该更新_curReleasePool
if (_releasePoolStack.size()
> 1)
{
_curReleasePool = _releasePoolStack.back();
}
}
static PoolManager*
s_singleInstance;//单例模式
std::deque< AutoreleasePool*>
_releasePoolStack;//管理用户创建的自动释放池用的盏
AutoreleasePool *_curReleasePool;//现在的自动释放池
};
AutoreleasePool
class CC_DLL AutoreleasePool
{
public:
/**
* 提示:自动释放池对象要创建在栈里面 不能再堆里面
* 创建的时候就自动push进PoolManager里面
*/
AutoreleasePool();
{
_managedObjectArray.reserve(150);//vector扩大容量
PoolManager::getInstance()->push( this);
}
/**
* 用引用来创建 是为了调试
*/
AutoreleasePool( const std::string &name);
{
_managedObjectArray.reserve(150);
PoolManager::getInstance()->push( this);
}
// 枚举每一个加进对象池的obj去调用release 并且清空
~AutoreleasePool();
{
CCLOGINFO( "deallocing
AutoreleasePool: %p" , this);
clear();//
PoolManager::getInstance()->pop();
}
/**
* 添加对象到对象池中
* 对象池销毁的时候会调用
*/
void addObject( Ref *object);
{
_managedObjectArray.push_back( object);
}
/**
清理对象池 析构函数调用
*/
void clear();
{
#if defined (COCOS2D_DEBUG)
&& ( COCOS2D_DEBUG > 0)
_isClearing = true;
#endif
for (const auto &obj
: _managedObjectArray)
{
//枚举每一个加进对象池的obj去调用release
obj->release();
}
//把vector清空
_managedObjectArray.clear();
#if defined (COCOS2D_DEBUG)
&& ( COCOS2D_DEBUG > 0)
_isClearing = false;
#endif
}
#if defined (COCOS2D_DEBUG)
&& ( COCOS2D_DEBUG > 0)
/**
* Whether the pool is doing `clear` operation.
*/
bool isClearing() const { return _isClearing;
};
#endif
/**
* 检查是否包含
* 枚举一遍这个vector
*/
bool contains( Ref*
object) const ;
{
for (const auto&
obj : _managedObjectArray)
{
if (obj
== object )
return true ;
}
return false;
}
/**
* 用来调试
*
*/
void dump();
{
CCLOG("autorelease
pool: %s, number of managed object %d\n", _name.c_str(), static_cast<int >(_managedObjectArray.size()));
CCLOG("%20s%20s%20s", "Object
pointer", "Object id" , "reference
count");
for (const auto &obj
: _managedObjectArray)
{
CC_UNUSED_PARAM(obj);
CCLOG("%20p%20u\n" ,
obj, obj->getReferenceCount());
}
}
private:
/**
* The underlying array of object managed by the pool.
*
* Although Array retains the object once when an object is added, proper
* Ref::release() is called outside the array to make sure that the pool
* does not affect the managed object‘s reference count. So an object can
* be destructed properly by calling Ref::release() even if the object
* is in the pool.
*/
std::vector< Ref*>
_managedObjectArray;
std::string _name;
#if defined (COCOS2D_DEBUG)
&& ( COCOS2D_DEBUG > 0)
/**
* The flag for checking whether the pool is doing `clear` operation.
*/
bool _isClearing;
#endif
};
下面这张图是网上找的类图继承图: