`

cocos2dx 内存管理

c++ 
阅读更多
cocos2dx 内存管理
转载自:http://blog.csdn.net/ring0hx/article/details/7946397

cocos2dx的内存管理移植自Objective-C, 对于没有接触过OC的C++开发人员来说是挺迷惑的。不深入理解内存管理是无法写出好的C++程序的,我用OC和cocos2dx也有一段时间了,在此总结一下,希望对想用cocos2dx开发游戏的朋友有所帮助。

C++的动态内存管理一般建议遵循谁申请谁释放的原则,即谁通过new操作符创建了对象,谁就负责通过delete来释放对象。如果对象的生命周期在一个函数内,这很容易做到,在函数返回前delete就行了。但一般我们在函数中new出来的对象的生命周期都会超出该函数体(例如作为函数的返回值),否则我们可以直接在栈上创建对象,不需要使用动态内存,也省去了内存管理的麻烦(当然大对象是不适合在栈上分配的)。如果对象的生命周期超出了创建对象的函数,我们就很难再遵循谁申请谁释放的原则了,我们必须在函数外的某个合适的地方释放对象,如果这个对象同时被多个对象引用,问题就很复杂了,必须保证所有该对象的引用者都不再需要它了才可以释放,在实际使用中这点是很难保证的。于是,各种内存管理技术应运而生了:垃圾回收器,智能指针,引用计数...... cocos2dx移植于Objective-C,因此和OC一样使用了比较原始的引用计数的方法来管理内存。

cocos2dx通过CCObject和CCPoolManager来实现内存管理。所有使用cocos2dx引用计数机制的类都必须派生自CCObject。CCObject有一个计数器成员变量m_uReference,当CCObject被构造时m_uReference=1,表示该对象被引用1次。CCObject的retain方法可以使计数器加1,release方法可以使计数器减1。当计数器减到0时release方法会通过delete this来销毁自己。

手动内存管理
使用retain和release,我们可以手动管理内存, 通过new 创建的对象,使用release来释放。
CCObject *obj=new CCObject();

obj->release();
和new\delete需配对使用一样,new\release也要配对使用才可确保内存被释放。有人会说这个把delete换成release有意义吗?需要注意的是这个的release并不等同于delete,release只是表示引用计数减1,并不是真正销毁obj所占用的内存。只有当obj的引用计数为0时内存才会被销毁。下面的代码就展示了release和delete不同:
CCArray *array = CCArray::array();
CCObject *obj = new CCObject();// m_uReference=1
array->addObject(obj); // CCArray的addObject方法会自动调用obj的retain方法,使引用计数加1,表示拥有obj,此时m_uReference=2
obj->release(); // 这里的release和new配对,obj引用计数减1,但是并不会释放obj, 此时m_uReference=1;
obj->doSomething(); // 在release之后我们依然可以正常使用obj,它并没有被释放
array->removeObject(obj); //当我们把obj从CCArray中移除时,CCArray会自动调用obj的release,此时m_uReference=0, obj被销毁
obj->doSomething(); // 错误,obj已经被销毁
对于手动内存管理,我们需遵循new/release,retain/release配对使用的原则,谁new,谁release;谁retain,谁release。new出来的对象如果是要加入到cocos2dx集合中,添加完后一定不要忘记release,集合类已经为你retain了对象,你还是要为你的new配对release一次,否则当这个对象从集合中移除时不会被正确销毁。

自动内存管理
手动内存管理似乎比new/delete更麻烦,而且并没有解决一开始我们提到的函数内创建的对象的生命周期超出函数怎么办的问题。new和release需配对使用,那在函数内创建的对象返回前我们需要调用一次release,在这之前如果我们没有把对象加入到什么集合中,对象就被销毁了,和使用new/delete是一样的。自动内存管理就可以解决这个问题。CCObject有一个autorelease方法,如果一个对象在用new关键字创建之后调用了autorelease,我们就不必关心它的释放问题。CCPoolManager会在游戏的每一帧结束后自动释放这些autorelease的对象。CCPoolManager其实依然是通过引用计数来管理对象生命周期的,它里面有一个CCAutoreleasePool,我们调用CCObject的autorelease就是把自己加入到CCAutoreleasePool的对象数组里面。当每一帧结束的时候,CCPoolManager会将对象从数组中移除,如果这时候对象的引用计数为0,对象就自然被释放了。对于用new关键字创建之后调用了autorelease的对象,不需要再release一次。

cocos2dx中的大部分对象都可以通过静态工厂方法来创建出这种会自动释放的对象,这是cocos2dx的一条规则,我们自己实现的类最好也遵循这样的规则,以免引起其他开发人员误会。如果一个对象是通过类的静态方法创建而不是new出来的,我们就不需要release它。

其实这里的自动并没有我们想得那么好,对于像C#,Java这种托管语言,虚拟机为你完成了所有内存管理工作,程序员完全从内存分配和释放中解脱了出来。cocos2dx的autorelease只不过每帧结束后自动在为我们释放了一次对象,如果我们希望创建的对象在下一帧仍然可以使用,我们需要显式地retain一下这个对象或者把对象加入到集合中(集合会帮我们retain一次)。既然retain了,我们还是不能忘记在适当的地方release。比较常见的用法是创建一个autorelease对象作为类成员变量,我们在通过静态方法得到实例的指针后除了赋值给类成员,还要retain一次,然后在类的析构函数中release一次。如果没有retain,以后使用该成员的时候就会因为对象被销毁而发生内存访问错误,这是新手很容易遇到的陷阱。
分享到:
评论

相关推荐

    Cocos2D-X2.2.3学习笔记3(内存管理)

    Cocos2D-X2.2.3学习笔记3(内存管理) http://blog.csdn.net/hucblog/article/category/2242181

    Cocos2D-X游戏开发技术精解.pdf

    Cocos2D-X引擎的文件操作模块和内存管理机制;各种各样的粒子效果;如何掌握利用Lua脚本制作游戏的能力;Cocos2D-HTML5引擎版本;引擎的附加功能等。最后,《Cocos2D-X游戏开发技术精解》和读者一起展望了Cocos2D-X...

    Cocos2D-X游戏开发技术精解

    第1章 Cocos2D-X引擎的介绍 1 1.1 何为游戏引擎 1 1.1.1 游戏的核心—引擎 1 1.1.2 引擎的特点 2 1.1.3 知名的引擎介绍 4 1.1.4 引擎的分类 5 1.2 Cocos2D-X引擎的来历 8 1.3 引擎的版本 9 1.4 下载与安装 10 1.5 ...

    cocos2d-x游戏开发之旅

    介绍Cocos2d-x更高阶的内容,包括渲染效率的提高、动画、TexturePacker图片打包、Tiled地图游戏实例、定时器、函数回调、内存管理、数据保存、Csv文件读取。介绍Lua、有限状态机启蒙知识和应用。分享基于Cocos2d-X的...

    Cocos2d-x实战 C++卷,完整扫描版

    全书内容涵盖了Cocos2d-x的核心类、瓦片地图、物理引擎、音乐音效、数据持久化、网络通信、数据交换格式、内存管理、性能优化、平台移植、程序代码管理、三大应用商店发布产品等。本书共29章,按内容结构可分为六篇...

    Cocos2d-x的内存管理总结

    主要介绍了Cocos2d-x的内存管理总结,详解探讨了手工对象内存管理、自动对象内存管理、自动释放的时机等问题,需要的朋友可以参考下

    Learn iPhone and iPad cocos2d Game Development

     2.3 cocos2d中的内存管理问题  2.4 改变世界  2.5 你还应该知道的  2.5.1 ios设备  2.5.2 关于内存的使用  2.5.3 模拟器  2.5.4 关于日志  2.6 本章小结 第3章 基础知识  3.1 cocos2d中的单件类  3.2 ...

    cocos2d-xccobject

    ccobject cocos2d-xcocos2d-x最初移植自cocos2d的objective C版本。因此,在内存管理上,使用了和NSObject类似的引用计数器方法,相关接口放置在CCObject类中。

    Cocos2d-x开发中C++内存管理

    始并没有介绍C++语言,C++的内存管理当然也没进行不论什么的说明,为了掌握Cocos2d-x中的内存管理机制,是有必要先了解一些C++内存管理的知识。  C++内存管理非常复杂,假设全然地系统地介绍可能须要一本书的篇幅...

    剖析iOS开发中Cocos2d-x的内存管理相关操作

    主要介绍了剖析iOS开发中Cocos2d-x的内存管理相关操作,Cocos2d-x是开发游戏的利器,需要的朋友可以参考下

    modules-for-cocos2d-x:cocos2d-x 模块,如数据管理器和其他工具

    cocos2d-x版本:3.2 ##1. 单元测试 所有的模块的单元测试在test文件夹下。 ios,mac用户打开test/proj.ios_mac/test.xcodeproj, 修改部分引用路径,直接编译运行即可。 android用户可以将test/proj.andorid项目导入到...

    Cocos2d-x 3.x入门教程(二):Node节点类

    Node类是Cocos2d-x中一个非常重要的类,它继承自类Ref,关于Ref类,Ref类是一个内存管理的类,我后续也会总结的,这里就不做多说了。 Node类在Cocos2d-x中有多重要呢?任何需要画在屏幕上的对象都是节点类。最常用的...

    C++基础入门教程(五):new和delete

    对于以前没有接触过C++,然后初次接触Cocos2d-x的朋友来说,可能对于内存管理方面会比较生疏。 也经常会因为内存问题导致各种小Bug,我也曾经写过一篇retain和release倒底怎么玩?,用来驾驭Cocos2d-x的对象引用和...

Global site tag (gtag.js) - Google Analytics