`

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的学习过程中,内存管理是至关重要的一个环节,它直接影响到游戏的性能和稳定性。Cocos2D-X是一个跨平台的2D游戏开发框架,使用C++作为主要编程语言,并支持Lua和JavaScript。本笔记将深入探讨Cocos...

    cocos2d-x-cocos2d-x-2.2.2.zip

    cocos2d-x不仅适用于游戏开发,还可以用于创建教育软件、互动媒体和其他2D图形应用,其强大的场景管理、精灵(Sprite)系统和粒子效果等功能,使得开发者能够快速构建各种复杂的2D场景。 总的来说,cocos2d-x 2.2.2...

    Cocos2d-x实战 JS卷 Cocos2d-JS开发

    8. **性能优化**:提供关于代码优化、内存管理和渲染优化的建议,以提高游戏性能。 9. **发布与跨平台**:指导如何将游戏打包并发布到不同的平台,如iOS、Android和Web。 10. **Cocos2d-JS特定特性**:可能包含...

    Cocos2d-x实战C++卷关东升著完整版pdf

    本书可能会详细讲解Cocos2d-x中的内存管理机制,如自动引用计数(ARC)和弱引用,以及如何通过优化代码和数据结构来提高游戏运行效率。 最后,还会涉及到Cocos2d-x的构建系统和发布流程,包括多平台支持、资源打包...

    经典版本 方便下载 源码 旧版本 3.8 官网找不到了 cocos2d-x-3.8.zip

    11. **性能优化**:3.8版本在内存管理和渲染效率上进行了优化,确保游戏运行流畅。 12. **扩展性**:cocos2d-x提供了插件系统和扩展API,方便开发者添加自定义功能和第三方库。 在学习和使用cocos2d-x 3.8时,...

    Cocos2d-x 3.x游戏开发实战pdf含目录

    最后,本书可能会探讨性能优化技巧,如内存管理、渲染优化、代码调试等,帮助开发者提升游戏运行效率,确保游戏在各种设备上都能流畅运行。 总的来说,《Cocos2d-x 3.x游戏开发实战》是一本全面覆盖Cocos2d-x 3.x...

    Cocos2d-x实战:C++卷(2版)源代码

    C++的使用可以提供更好的性能和更直接的内存管理,同时也能充分利用面向对象编程的特性来构建复杂的游戏逻辑。 源代码部分通常包含以下关键知识点: 1. **场景(Scene)与层(Layer)管理**:Cocos2d-x使用场景和...

    Cocos2d-x实战 JS卷

    《Cocos2d-x实战 JS卷》是一本深入探讨Cocos2d-x游戏开发的专著,主要聚焦于使用JavaScript语言进行游戏编程。Cocos2d-x是一个开源的游戏开发框架,广泛应用于移动设备和桌面平台,支持iOS、Android、Windows等多...

    cocos2d-x-3.13.1 spine3.6.zip

    在资源管理方面,Cocos2d-x 3.13.1版本优化了资源加载和释放机制,这有利于减少内存消耗,提高游戏性能。开发者需要确保正确地加载和释放Spine动画资源,避免内存泄漏。此外,考虑到移动设备的性能限制,合理地优化...

    cocos2d-x-2.1.4.rar

    1. 性能优化:2.1.4版本对内存管理、渲染效率等方面进行了优化,降低了游戏运行时的资源消耗,提高了游戏的运行速度。 2. 稳定性提升:修复了大量的bug,确保了框架在各种环境下的稳定运行,减少了游戏崩溃的可能性...

    cocos2d-x-3.1.zip

    10. **性能优化**:Cocos2d-x 3.1对内存管理和渲染效率进行了优化,以确保在不同设备上的流畅运行。 11. **脚本支持**:虽然3.1版本主要以C++为主,但Cocos2d-x也支持Lua和JavaScript,允许开发者选择更适合自己的...

    cocos2d-iphone-2.0.tar.gz

    11. **Performance Improvements**:Cocos2d-iPhone 2.0在性能上做了大量优化,包括更快的渲染、内存管理和多线程支持。 12. **Multitouch Support**:针对iOS设备的多点触控特性,Cocos2d-iPhone提供了易于使用的...

    cocos2d-x 跑酷源码

    总结,通过深入研究"runningGame"的源码,我们可以了解到cocos2d-x在跑酷游戏开发中的应用,掌握从资源管理到游戏逻辑实现的全过程。这对于开发者来说,既是一次实践操作的锻炼,也是一次理论知识的巩固,对于后续的...

    cocos2d js api 中文文档

    7. **场景管理(Scene Management)**:场景是游戏的逻辑单位,Cocos2d-js提供了一种场景切换机制,允许在不同场景间平滑过渡。 8. **图集和精灵表(Atlases & Sprite Sheets)**:为了优化性能,Cocos2d-js支持...

    cocos2d-x-3.13.1.zip

    1. 性能提升:cocos2d-x 3.13.1版本在性能方面做了大量优化,包括内存管理、渲染效率等方面的改进,使得游戏运行更加流畅。 2. 脚本支持:该版本增强了Lua和JavaScript的绑定,让开发者可以选择更适合自己的脚本语言...

    Cocos2d-JS---demo

    9. **性能优化**:Cocos2d-JS 进行了多方面的性能优化,包括内存管理、渲染性能等,确保在不同设备上都能流畅运行。 在这个“js-tests”目录下,可能包含了各种 Cocos2d-JS 的功能测试案例,比如精灵动画、粒子效果...

    第3章 Cocos2d-x架构一瞥

    Cocos2d-x还提供了一些基础功能模块,如内存管理模型、纹理资源的加载和缓存,以及一组数据容器,使得STL中的容器能够与Cocos2d-x的内存管理模型相结合。 渲染系统作为Cocos2d-x的核心部分,它不仅负责场景元素的...

    cocos2d 入门教程

    cocos2d 提供了纹理图集(Texture Atlas)和plist文件来优化资源加载,减少内存占用。 七、发布与调试 完成游戏开发后,你需要打包应用并进行测试。cocos2d 支持在模拟器和真机上进行调试,通过Xcode的调试工具可以...

    cocos2d-x嵌入webview

    同时,优化Webview的内存管理和渲染性能,如合理设置缓存策略,避免内存泄漏,以及在不影响用户体验的前提下,适时暂停或恢复Webview的加载。 总结,cocos2d-x嵌入Webview是提升游戏功能和用户体验的重要手段。...

    cocos2d-x版本的对对碰代码

    Cocos2d-x有内置的资源管理模块,如Texture2D、SpriteFrameCache等,用于加载和缓存图像资源,AudioEngine用于播放音频。 6. **Lua脚本集成**:Cocos2d-x支持Lua作为脚本语言,可以用来编写游戏逻辑,与C++代码混合...

Global site tag (gtag.js) - Google Analytics