class
CC_DLL
Ref
public
:
CCassERT
(_referenceCount > 0,
"reference count should greater than 0"
);
++_referenceCount;
}
*/
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();
//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
#endif
}
* 自动释放 也就是当前的AutoReleasePool被调用了析构函数之后 引擎全局有一个
AutoReleasePool
*/
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;
#endif
#if
CC_USE_MEM_LEAK_DETECTION
#endif
}
public
:
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
:
void
push(
AutoreleasePool
*pool);
_releasePoolStack.push_BACk(
pool
);
_curReleasePool =
pool
;
}
// 如果是弹出第一个
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;//现在的自动释放池
};
class
CC_DLL
AutoreleasePool
public
:
* 提示:自动释放池对象要创建在栈里面 不能再堆里面
* 创建的时候就自动push进PoolManager里面
*/
_managedObjectArray.reserve(150);//vector扩大容量
PoolManager
::geTinstance()->push(
this
);
}
* 用引用来创建 是为了调试
*/
_managedObjectArray.reserve(150);
PoolManager
::geTinstance()->push(
this
);
}
//
枚举每一个加进对象池的obj去调用release 并且清空
CCLOGINFO
(
"deallocing AutoreleasePool: %p"
,
this
);
PoolManager
::geTinstance()->pop();
}
* 添加对象到对象池中
* 对象池销毁的时候会调用
*/
清理对象池 析构函数调用
*/
#if
defined
(
COCOS2D_DEBUG
) && (
COCOS2D_DEBUG
> 0)
_isClearing =
true
;
#endif
for
(
const
auto
&obj : _managedObjectArray)
//枚举每一个加进对象池的obj去调用release
}
//把vector清空
_managedObjectArray.clear();
#if
defined
(
COCOS2D_DEBUG
) && (
COCOS2D_DEBUG
> 0)
#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)
return
true
;
}
}
* 用来调试
*
*/
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)
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
*/
std::
vector
<
Ref
*> _managedObjectArray;
#if
defined
(
COCOS2D_DEBUG
) && (
COCOS2D_DEBUG
> 0)
* The flag for checking whether the pool is doing `clear` operation.
*/
bool
_isClearing;
#endif
};
下面这张图是网上找的类图继承图: