void DisplayLinkDirector::mainLoop()
{
if (_purgeDirectorInNextLoop)
{
_purgeDirectorInNextLoop = false;
purgeDirector();
}
else if (! _invalid)
{
drawScene();
// release the objects
//清空 当前内存池的
PoolManager::getInstance()->getCurrentPool()->clear();
}
}
Ref
说起凡是需要进行自动内存管理的对象都要继承自Ref
类。
class CC_DLL Ref
{
public:
void retain();
void release();
Ref* autorelease();
unsigned int getReferenceCount() const;
protected:
Ref();
public:
//析构函数 为 虚函数 从而可以保证正确的析构函数可以被调用
virtual ~Ref();
protected:
//传说中的 引用计数
unsigned int _referenceCount;
friend class AutoreleasePool;
};
其实现也很简单。
//初始的时候 为1
Ref::Ref()
: _referenceCount(1) // when the Ref is created, the reference count of it is 1
{
}
Ref::~Ref()
{
}
void Ref::retain()
{
//计数 加1
CCASSERT(_referenceCount > 0, "reference count should greater than 0");
++_referenceCount;
}
void Ref::release()
{
CCASSERT(_referenceCount > 0, "reference count should greater than 0");
--_referenceCount;
//如果为 0 就删除自身
if (_referenceCount == 0)
{
delete this;
}
}
Ref* Ref::autorelease()
{
//将其加入 自动内存管理
PoolManager::getInstance()->getCurrentPool()->addObject(this);
return this;
}
//获取 当前 引用计数
unsigned int Ref::getReferenceCount() const
{
return _referenceCount;
}
AutoreleasePool
的实现其主要思想为 以Node为例,当生成一个Node对象时,它的引用计数为1,然后她会主动加入到AutoreleasePool
中,。
一种情况是:当他被加入到父节点,此时父节点将他的计数加1。在这一帧最后,AutoreleasePool
进行清理,将该对象计数减1,此时计数为1。AutoreleasePool
清理后将管理的队列清空,因为他只管这一帧的,此后他也是安然无恙,当父节点移除他之后,它的计数为0,因此调用析构函数清理。
另一种情况,没有父节点收留他,一直计数为1,到这一帧最后AutoreleasePool
进行清理,将该对象计数减1,此时计数为0,因此调用析构函数清理,合理。
class CC_DLL AutoreleasePool
{
public:
AutoreleasePool();
//给个名字
AutoreleasePool(const std::string &name);
~AutoreleasePool();
//添加 管理对象
void addObject(Ref *object);
//清理
void clear();
//检查是否包含 某个对象
bool contains(Ref* object) const;
private:
//很简单 就是一个vector
std::vector<Ref*> _managedObjectArray;
//名字
std::string _name;
};
//其具体实现
AutoreleasePool::AutoreleasePool()
: _name("")
{
_managedObjectArray.reserve(150);
PoolManager::getInstance()->push(this);
}
AutoreleasePool::AutoreleasePool(const std::string &name)
: _name(name)
{
//预分配 150个 空间
_managedObjectArray.reserve(150);
//将自身加入到PoolManager
PoolManager::getInstance()->push(this);
}
AutoreleasePool::~AutoreleasePool()
{
//清理 后 将自身出栈
clear();
PoolManager::getInstance()->pop();
}
void AutoreleasePool::addObject(Ref* object)
{
_managedObjectArray.push_back(object);
}
void AutoreleasePool::clear()
{
//对每一个 管理的 对象 执行其release
for (const auto &obj : _managedObjectArray)
{
obj->release();
}
//最重要的是 清空了 vector 只是对这一帧的对象进行管理
_managedObjectArray.clear();
}
//看是否 包含
bool AutoreleasePool::contains(Ref* object) const
{
//逐个遍历 看是否包含 这个对象
for (const auto& obj : _managedObjectArray)
{
if (obj == object)
return true;
}
return false;
}
PoolManager
的实现AutoreleasePool
本身是为了在每一帧的末尾使用,也就是说需要清理的对象(即为管理的引用计数为1对象)在这一帧的末尾清理,但是还存在有些帧生成了大量需要清理的对象,因此需要在某些情况下,实现用户自定义的AutoreleasePool
来缩短清理周期。这就是 PoolManager
起的作用。
{
//此时 其构造函数 已经将自身加入到 PoolManager中
//也就是 目前所有的 管理工作由这个新生成的接管
new AutoreleasePool();
auto p1=new Node();
p1->autorelease();
auto p2=new Node();
p2->autorelease();
auto p3=new Node();
p3->autorelease();
//出了这个 花括号
//周期过了 进行清理 将自身出栈
//来达到 小于一个帧的目的
}
看看 PoolManager
class CC_DLL 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;
//也是很简单 只是用来装 AutoreleasePool
std::vector<AutoreleasePool*> _releasePoolStack;
};
//实现
PoolManager* PoolManager::s_singleInstance = nullptr;
PoolManager* PoolManager::getInstance()
{
if (s_singleInstance == nullptr)
{
s_singleInstance = new (std::nothrow) PoolManager();
// Add the first auto release pool
//这是第一个 它的构造函数 就会找到这个PoolManager并加入。
new AutoreleasePool("cocos2d autorelease pool");
}
return s_singleInstance;
}
void PoolManager::destroyInstance()
{
delete s_singleInstance;
s_singleInstance = nullptr;
}
PoolManager::PoolManager()
{
_releasePoolStack.reserve(10);
}
PoolManager::~PoolManager()
{
//挨个删除
while (!_releasePoolStack.empty())
{
AutoreleasePool* pool = _releasePoolStack.back();
delete pool;
}
}
AutoreleasePool* PoolManager::getCurrentPool() const
{
//返回栈顶pool
return _releasePoolStack.back();
}
bool PoolManager::isObjectInPools(Ref* obj) const
{
//逐个 遍历 其管理的 池子 看是否包含本对象
for (const auto& pool : _releasePoolStack)
{
if (pool->contains(obj))
return true;
}
return false;
}
void PoolManager::push(AutoreleasePool *pool)
{
//入栈
_releasePoolStack.push_back(pool);
}
void PoolManager::pop()
{
//出栈
_releasePoolStack.pop_back();
}
RefPtr
的实现他是仿照share_ptr
实现的。对于单个元素,如要内存自动管理,则要手动进行release
和retain
,很不方便。因此将其进行一层封装,将其包装到局部变量的析构/构造函数中,方便计数管理。
//对于 do{}while(0);方式的宏使用方式 可参考 https://www.jianshu.com/p/99efda8dfec9
#define CC_REF_PTR_SAFE_RETAIN(ptr)\
\
do\
{\
if (ptr)\
{\
const_cast(static_cast(ptr))->retain();\
}\
\
} while (0);
#define CC_REF_PTR_SAFE_RELEASE(ptr)\
\
do\
{\
if (ptr)\
{\
const_cast(static_cast(ptr))->release();\
}\
\
} while (0);
#define CC_REF_PTR_SAFE_RELEASE_NULL(ptr)\
\
do\
{\
if (ptr)\
{\
const_cast(static_cast(ptr))->release();\
ptr = nullptr;\
}\
\
} while (0);
//具体实现
template <typename T> class RefPtr
{
public:
inline RefPtr()
:
_ptr(nullptr)
{
}
//移动构造函数
inline RefPtr(RefPtr<T> && other)
{
_ptr = other._ptr;
other._ptr = nullptr;
}
inline RefPtr(T * ptr)
:
_ptr(const_cast<typename std::remove_const<T>::type*>(ptr)) // Const cast allows RefPtr to reference objects marked const too.
{
CC_REF_PTR_SAFE_RETAIN(_ptr);
}
inline RefPtr(std::nullptr_t ptr)
:
_ptr(nullptr)
{
}
inline RefPtr(const RefPtr<T> & other)
:
_ptr(other._ptr)
{
CC_REF_PTR_SAFE_RETAIN(_ptr);
}
inline ~RefPtr()
{
CC_REF_PTR_SAFE_RELEASE_NULL(_ptr);
}
inline RefPtr<T> & operator = (const RefPtr<T> & other)
{
if (other._ptr != _ptr)
{
CC_REF_PTR_SAFE_RETAIN(other._ptr);
CC_REF_PTR_SAFE_RELEASE(_ptr);
_ptr = other._ptr;
}
return *this;
}
inline RefPtr<T> & operator = (RefPtr<T> && other)
{
if (&other != this)
{
CC_REF_PTR_SAFE_RELEASE(_ptr);
_ptr = other._ptr;
other._ptr = nullptr;
}
return *this;
}
inline RefPtr<T> & operator = (T * other)
{
if (other != _ptr)
{
CC_REF_PTR_SAFE_RETAIN(other);
CC_REF_PTR_SAFE_RELEASE(_ptr);
_ptr = const_cast<typename std::remove_const<T>::type*>(other); // Const cast allows RefPtr to reference objects marked const too.
}
return *this;
}
inline RefPtr<T> & operator = (std::nullptr_t other)
{
CC_REF_PTR_SAFE_RELEASE_NULL(_ptr);
return *this;
}
// Note: using reinterpret_cast<> instead of static_cast<> here because it doesn't require type info.
// Since we verify the correct type cast at compile time on construction/assign we don't need to know the type info
// here. Not needing the type info here enables us to use these operations in inline functions in header files when
// the type pointed to by this class is only forward referenced.
inline operator T * () const { return reinterpret_cast<T*>(_ptr); }
inline T & operator * () const
{
CCASSERT(_ptr, "Attempt to dereference a null pointer!");
return reinterpret_cast<T&>(*_ptr);
}
inline T * operator->() const
{
//使用 reinterpret_cast 不需要类型信息
return reinterpret_cast<T*>(_ptr);
}
inline T * get() const { return reinterpret_cast<T*>(_ptr); }
inline bool operator == (const RefPtr<T> & other) const { return _ptr == other._ptr; }
inline bool operator == (const T * other) const { return _ptr == other; }
inline bool operator == (typename std::remove_const<T>::type * other) const { return _ptr == other; }
inline bool operator == (const std::nullptr_t other) const { return _ptr == other; }
inline bool operator != (const RefPtr<T> & other) const { return _ptr != other._ptr; }
inline bool operator != (const T * other) const { return _ptr != other; }
inline bool operator != (typename std::remove_const<T>::type * other) const { return _ptr != other; }
inline bool operator != (const std::nullptr_t other) const { return _ptr != other; }
inline bool operator > (const RefPtr<T> & other) const { return _ptr > other._ptr; }
inline bool operator > (const T * other) const { return _ptr > other; }
inline bool operator > (typename std::remove_const<T>::type * other) const { return _ptr > other; }
inline bool operator > (const std::nullptr_t other) const { return _ptr > other; }
inline bool operator < (const RefPtr<T> & other) const { return _ptr < other._ptr; }
inline bool operator < (const T * other) const { return _ptr < other; }
inline bool operator < (typename std::remove_const<T>::type * other) const { return _ptr < other; }
inline bool operator < (const std::nullptr_t other) const { return _ptr < other; }
inline bool operator >= (const RefPtr<T> & other) const { return _ptr >= other._ptr; }
inline bool operator >= (const T * other) const { return _ptr >= other; }
inline bool operator >= (typename std::remove_const<T>::type * other) const { return _ptr >= other; }
inline bool operator >= (const std::nullptr_t other) const { return _ptr >= other; }
inline bool operator <= (const RefPtr<T> & other) const { return _ptr <= other._ptr; }
inline bool operator <= (const T * other) const { return _ptr <= other; }
inline bool operator <= (typename std::remove_const<T>::type * other) const { return _ptr <= other; }
inline bool operator <= (const std::nullptr_t other) const { return _ptr <= other; }
inline operator bool() const { return _ptr != nullptr; }
inline void reset()
{
CC_REF_PTR_SAFE_RELEASE_NULL(_ptr);
}
inline void swap(RefPtr<T> & other)
{
if (&other != this)
{
Ref * tmp = _ptr;
_ptr = other._ptr;
other._ptr = tmp;
}
}
//弱引用 不增加计数
inline void weakAssign(const RefPtr<T> & other)
{
CC_REF_PTR_SAFE_RELEASE(_ptr);
_ptr = other._ptr;
}
private:
Ref * _ptr;
};
下一篇 分析 音频系统 的实现。