加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Cocos2d-X 学习笔记 19 cocos2d-x学习之自动内存管理和常见宏

发布时间:2020-12-14 19:14:55 所属栏目:百科 来源:网络整理
导读:1.自动内存管理 1)概述 C++语言默认是没有提供自动内存管理的。使用者需要自己分配,自己释放。在cocos2d-x里提供了一个自动内存管理的方案。主要是通过CCObject来提供的,用户只要继承了CCObject,就可以通过调用autorelease()来告诉系统进行自动内存管理

1.自动内存管理

1)概述

C++语言默认是没有提供自动内存管理的。使用者需要自己分配,自己释放。在cocos2d-x里提供了一个自动内存管理的方案。主要是通过CCObject来提供的,用户只要继承了CCObject,就可以通过调用autorelease()来告诉系统进行自动内存管理。

一般用法就是:CCLayer* pLayer = CreateLayer(s_nActionIdx);pLayer->autorelease();

2)自动内存管理的实现

自动内存管理的实现原理大概是:用户设置自动释放功能时,内存管理(CCPoolManager)会自动把这个CCObject对象加入其管理池中。等到一定时机(场景销毁,一帧渲染结束,程序退出等),内存管理会遍历其所管理的每一个对象,逐个调用CCObject的释放函数进行释放。CCObject自己内部设置一个引用系数,增加一个使用就系数加一,释放就系数减一,当系数为0时,才真正进行释放。

如果研究下CCPoolManager,会发现进行真正内存管理的是自动释放池(CCAutoreleasePool),CCPoolManager下面包含有多个CCAutoreleasePool。CCAutoreleasePool提供了addObject,removeObject,clear功能。我开始很疑惑,因为进行内存释放管理,一个CCAutoreleasePool就够了。后来仔细考虑,发现了这个的秘密所在:

CCPoolManager管理多个CCAutoreleasePool,是为了方便确定哪个自动释放池(CCAutoreleasePool)可以进行释放,而不用影响到其他的自动释放池。比如在关卡切换时,上一个关卡的自动释放池的数据就可以进行自动释放了,而新关卡的自动释放池不变~~ 好想法!

我们已经知道,调用了autorelease()方法的对象(下面简称"autorelease对象"),将会在自动回收池释放的时候被释放一次。虽然,Cocos2d-x已经保证每一帧结束后释放一次回收池,并在下一帧开始前创建一个新的回收池,但是我们也应该考虑到回收池本身维护着一个将要执行释放操作的对象列表,如果在一帧之内生成了大量的autorelease对象,将会导致回收池性能下降。因此,在生成autorelease对象密集的区域(通常是循环中)的前后,我们最好可以手动创建并释放一个回收池。
? 我们可以通过回收池管理器CCPoolManager的push()或pop()方法来创建或释放回收池,其中的CCPoolManager也是一个单例对象。在这里,我们通过这段简单的代码来分析自动回收池的嵌套机制:
? CCPoolManager::sharedPoolManager()->push();
? for(int i=0; i<n; i++)
? {
? CCString* dataItem = CCString::createWithFormat("%d",Data[i]);
? stringArray->addObject(dataItem);
? }
? CCPoolManager::sharedPoolManager()->pop();


2.常见宏

1)NS_CC_BEGIN cocos2d命名空间开始

2) NS_CC_ENDcocos2d命名空间结束

3)USING_NS_CC 声明cocos2d命名空间

4)CC_SYNTHESIZE_READONLY(varType,varName,funName)声明一个成员变量以及getfunName函数,没有set函数。getfunName已经实现,其实现就是返回这个值。

5)CC_SYNTHESIZE_READONLY_PASS_BY_REF(varType,funName) 类似CC_SYNTHESIZE_READONLY,不过getfunName返回的是引用。

6)CC_SYNTHESIZE(varType,funName) 声明一个成员变量以及getfunName,setfunName函数.函数声明和实现都有

7)CC_SYNTHESIZE_PASS_BY_REF(varType,funName) 类似CC_SYNTHESIZE,不过getfunName返回的是引用。

8)CC_PROPERTY_READONLY(varType,funName) 声明一个成员变量以及getfunName函数,没有set函数。getfunName函数的实现要自己做

9)CC_PROPERTY_READONLY_PASS_BY_REF(varType,funName) 类似CC_PROPERTY_READONLY,不过getfunName返回的是引用。getfunName函数的实现要自己做

10)CC_PROPERTY(varType,funName) 声明一个成员变量以及getfunName,setfunName函数.函数实现要自己做

11)CC_PROPERTY_PASS_BY_REF(varType,funName) 类似CC_PROPERTY,,不过getfunName返回的是引用

其实我们在游戏开发中 注意一些内存的管理,对游戏有很大的帮助!一点一点积攒起来!就会对游戏内存吃紧的问题!有本质的解决! 1,如场景切换 在内存吃紧的情况下 我们可以选择 先清理一下缓存! // 清空缓存 CCDirector::sharedDirector()->purgeCachedData(); 2,场景切换也有注意的地方!场景切换 有压入式加入!替换式加入! 这里说一下压入场景(pushScene)和弹出场景(popScene)。它们都可以用来显示场景 和保留当前场景并显示新场景 ;不同的是它们不把旧场景从内存中释放掉,这样可以提高加 载速度,这时需要注意,如果内存不足以支撑的话,建议采用replaceScene 函数。 以上过程分为以下三步: 1)调用 CCDirector::sharedDirector()->purgeCachedData() 清空缓存。 2)新建场景。 3)调用 CCDirector::sharedDirector()->replaceScene(this) 替换新场景。Cocos2D-x 提供了 场景间切换的特效,下一节将会介绍这些内容。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读