这几天在看我所理解的cocos2dx这个本书,看了几章后想给自己做个总结,如果哪里不对,请看到的人帮我指正出来,谢谢!
我所理解的cocos2dx这本书,主要是针对3.x以后的版本讲解了一些新添加的东西。
第二章
这一章主要对cocos2dx的一些架构做了详细的讲解,我主要总结cocos2dx的内存管理和UI树的绘制
cocos2dx引擎系统总览
cocos2dx内存管理
先总结一下c++11的三个智能指针
unique_ptr,shared_ptr,weak_ptr,
相同点:这三个智能指针都是模板类型的,都重载了“*”运算符,我们可以通过*p的方式访问所分配的堆内存,智能指针在析构和调用reset()函数时都会释放其内存。
不同点:
unique_ptr指针不能与其他的智能指针共享所指对象的内存,但是可以通过标准库的move函数来转移指针所指对象的"所有权“,一旦转移成功,原来的unique_ptr指针就失去了对对象内存的“所有权”,再次使用会出现错误。
多个shared_ptr可以共享同一堆分配对象的内存,它在实现上采用引用计数,即使一个shared_ptr指针放弃所指对象的”所有权“,也不会影响其他的shared_ptr指针,除非引用计数为零,才会真正释放所占有的堆内存。
weak_ptr指针可以用来只想shared_ptr指针分配的对象内存,但不拥有该内存。我们可以使用其Lock成员来访问其所指向内存的一个shared_ptr对象,当其所指的对象无效时,返回NULL,weak_ptr主要是用来检测shared_ptr指针的有效性
不使用智能指针的原因:
1.智能指针有比较大的性能损失。
2.智能指针需要显示声明。
cocos2dx内存管理机制
1.引用计数
cocos2dx所有的类基本都是继承Ref基类。Ref基类的主要作用就是对对象进行引用计数。
class CC_DLL Ref
{
public:
void retain();
void release();
Ref* autorelease();
unsigned int getReferenceCount() const;
protected:
Ref();
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;
/// scriptObject, support for swift
void* _scriptObject;
#endif
// Memory leak diagnostic data (only included when CC_USE_MEM_LEAK_DETECTION is defined and its value isn't zero)
#if CC_USE_MEM_LEAK_DETECTION
public:
static void printLeaks();
#endif
};
当一个对象使用new运算符分配内存时,引用计数为1,调用retain()函数引用计数加1,调用release()引用计数减一,同时当引用计数为零的时候,调用release函数时会自动调用delete函数删除对象释放内存。如果调用了retain,而忘记调用release,会导致内存泄露。
2.用autorelease()方法声明一个智能指针
cocos2dx利用autorelese()声明一个智能指针,但是不是c++11中所说的将这些指针与变量相关联,而是全部加入一个AutoReleasePool中,在每帧结束的时候对AutoReleasePool中的对象进行清理。换而言之就是一个智能指针的声明周期就是从被创建开始到当前帧结束为止。
下一章再继续写cocos2dx引入的智能指针RefPtr<T>