c++的内存管理一直以来都是个问题,也有多种实现方案,比如智能指针,使用引用计数等,cocos2d-x也需要涉及到内存的管理。

cocos2d-x是如何管理内存的呢?

cocos2d-x的内存管理主要使用引用计数的机制进行内存的自动管理或者手动管理

常用的谁 new 了,谁delete 。这种方式很容易造成内存的碎片,严重的可能会造成内存的泄露,因为不是每个程序员都会记得在哪释放

cocos2d-x的内存管理分为手动内存管理和自动内存管理。在内存管理中,有一个很重要的类CCObject .

类CCObject实现了内存的管理机制。看源码,注释有解释

class CC_DLL CCObject : public CCCopying
{
public: //这两个是支持lua等脚本语言用的,可以先不用管
unsigned int m_uID;
int m_nLuaID;
protected:
unsigned int m_uReference; //对象的引用计数的
unsigned int m_uAutoReleaseCount;//自动内存管理的
public:
CCObject(void);
virtual ~CCObject(void);
void release(void); // 自减1 , m_uReference == 0时,delete this,销毁自己
void retain(void); // 自增1 , m_uReference++ ;
CCObject* autorelease(void); // 自动内存管理的。CCPoolManager::sharedPoolManager()->addObject(this);CCPoolManager是个内存池管理的
CCObject* copy(void); // CCObject的拷贝机制,内部就一句代码 return copyWithZone(0); ,可见,是调用了copyWithZone
bool isSingleReference(void) const; // 判断是不是单个引用
unsigned int retainCount(void) const; // 返回引用数
virtual bool isEqual(const CCObject* pObject); //判断两个对象是否是同一个对象 virtual void acceptVisitor(CCDataVisitor &visitor);
virtual void update(float dt) {CC_UNUSED_PARAM(dt);};
friend class CCAutoreleasePool; // 把CCAutoreleasePool设为CCObject的友元类,是为了方便CCAutoreleasePool访问CCObject中的成员进而进行内存管理
};
   成员变量 m_uID 和 m_nLuaID 是关于支持lua脚本语言用的。暂时可以不用管
成员变量 m_uReference 为此类的一个实例引用的次数,初始化为 1 ,如果为0,则表明此实例没有被任何对象引用,则可以删除 , delete this
成员变量 m_uAutoReleaseCount 为此类的一个实例是否是自动释放内存的。初始化0,如果大于0,则表明是自动释放的。此前的cocos2d-x版本中,m_uAutoReleaseCount 是个bool类型的变量。 看下 CCObject 的类的实现代码:如下,有注释
CCObject::CCObject(void)
: m_nLuaID() // 支持lua脚本语言的,初始化为 0
, m_uReference() // 当创建一个CCObject对象时,引用计数加 1
, m_uAutoReleaseCount() // 自动释放内存的标识位, 等于0则表明不会自动释放,大于0表示对象会自动释放内存
{
static unsigned int uObjectCount = ; m_uID = ++uObjectCount;
} CCObject::~CCObject(void)
{
// 如果此对象已经具有自动释放内存机制,则把此对象从内存池中删除掉
if (m_uAutoReleaseCount > )
{
CCPoolManager::sharedPoolManager()->removeObject(this);//把此对象从内存池中删除掉
} //下面是支持lua脚本语言相关的
if (m_nLuaID)
{
CCScriptEngineManager::sharedManager()->getScriptEngine()->removeScriptObjectByCCObject(this);
}
else
{
CCScriptEngineProtocol* pEngine = CCScriptEngineManager::sharedManager()->getScriptEngine();
if (pEngine != NULL && pEngine->getScriptType() == kScriptTypeJavascript)
{
pEngine->removeScriptObjectByCCObject(this);
}
}
} CCObject* CCObject::copy()
{
//copy函数,直接调用copyWithZone,在这里没有用到
return copyWithZone();
} //释放内存
void CCObject::release(void)
{
CCAssert(m_uReference > , "reference count should greater than 0");
--m_uReference; //对象的引用计数减 1 if (m_uReference == )//如果引用计数为0,表明没有其它对象引用了,就删除对象,释放内存
{
delete this;
}
} void CCObject::retain(void)
{
CCAssert(m_uReference > , "reference count should greater than 0"); ++m_uReference; //如果引用一次,就要手动调用retain,把对象的引用加1
} CCObject* CCObject::autorelease(void)
{
//新创建的对象如果调用autorelease()函数,就把此对象加入到内存池管理器,此后就可以不再关心内存的释放了。
CCPoolManager::sharedPoolManager()->addObject(this);
return this;
} //判断对象是否只有一个引用
bool CCObject::isSingleReference(void) const
{
return m_uReference == ;
}
//返回引用的个数
unsigned int CCObject::retainCount(void) const
{
return m_uReference;
}
//判断两个对象是否相等
bool CCObject::isEqual(const CCObject *pObject)
{
return this == pObject;
} void CCObject::acceptVisitor(CCDataVisitor &visitor)
{
visitor.visitObject(this);
}
CCObject实现了内存的自动管理机制(autorelease())和内存释放(release())机制
接下来,介绍一下两个与内存管理相关的类 CCPoolManager和CCAutoreleasePool

最新文章

  1. PHP加载另一个文件类的方法
  2. saiku 展示优化第二步(要诀和技巧)
  3. Z/OS遇到的错误
  4. jQuery+Superfish制作下拉菜单
  5. RHEL7虚拟机实验快照
  6. Educational Codeforces Round 3 E (609E) Minimum spanning tree for each edge
  7. HDU-5391 Zball in Tina Town
  8. Junit 断言 assertThat Hamcrest匹配器
  9. [HNOI2012] 矿场搭建
  10. cssText 和 this
  11. spark 机器学习基础 数据类型
  12. JDK TOMCAT MYSQL 配置
  13. 正交矩阵、EVD、SVD
  14. MVC部署阿里云躺过的坑
  15. 关于mdb数据库在插入过程中报错->Syntax error in INSERT INTO statement.(sql语句没问题)
  16. jdk的下载
  17. Kafka文件存储机制及offset存取
  18. mysql locking
  19. C#中全局处理异常方式
  20. 2018.06.26 Dominator Tree--支配树

热门文章

  1. c# Wndproc的使用方法
  2. java反射学习笔记
  3. view坐标_ _ Android应用坐标系统全面详解
  4. 磁盘IO的性能指标
  5. 转:Android Webview 加载外部html时选择加载本地的js,css等资源文件
  6. study topics
  7. JS函数arguments数组获得实际传参数个数
  8. java对话框形式实现加减乘除
  9. 关于新闻,在线编辑器建表时此字段一定要为text
  10. CSS3基础 02(2D /3D)