位置: 编程技术 - 正文

cocos2dx 内存管理 防止遗忘(cocos creator内存性能优化)

编辑:rootadmin
Cocos2d-x中的引用计数(Reference Count)和自动释放池(AutoReleasePool)引用计数

推荐整理分享cocos2dx 内存管理 防止遗忘(cocos creator内存性能优化),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:cocos2dx内存管理机制,cocos creator 内存管理,cocos2dx内存优化,cocos 内存优化,cocos2d内存优化,cocos2dx内存优化,cocos2dx内存优化,cocos2dx内存优化,内容如对您有帮助,希望把文章链接给更多的朋友!

引用计数是c/c&#;&#;项目中一种古老的内存管理方式。当我8年前在研究一款名叫TCPMP的开源项目的时候,引用计数就已经有了。

iOS SDK把这项计数封装到了NSAutoreleasePool中。所以我们也在Cocos2d-x中克隆了一套CCAutoreleasePool。两者的用法基本上一样,所以假如你没有涉及过ios开发,你可以看看苹果官方文档NSAutoreleasePool Class Reference。

CCAutoreleasePool

Cocos2d-x的CCAutoreleasePool和cocoa的NSAutoreleasePool有相同的概念和API,但是有两点比较重要的不同:

CCAutoreleasePool不能被开发者自己创建。Cocos2d-x会为我们每一个游戏创建一个自动释放池实例对象,游戏开发者不能新建自动释放池,仅仅需要专注于release/retain cocos2d::CCObject的对象。

CCAutoreleasePool不能被用在多线程中,所以假如你游戏需要网络线程,请仅仅在网络线程中接收数据,改变状态标志,不要这个线程里面调用cocos2d接口。下面就是原因:

CCAutoreleasePool的逻辑是,当你调用object->autorelease(),object就被放到自动释放池中。自动释放池能够帮助你保持这个object的生命周期,直到当前消息循环的结束。在这个消息循环的最后,假如这个object没有被其他类或容器retain过,那么它将自动释放掉。例如,layer->addChild(sprite),这个sprite增加到这个layer的子节点列表中,他的声明周期就会持续到这个layer释放的时候,而不会在当前消息循环的最后被释放掉。

这就是为什么你不能在网络线层中管理CCObject生命周期,因为在每一个UI线程的最后 ,自动释放对象将会被删除,所以当你调用这些被删掉的对象的时候,你就会遇到crash。

1CCObject::release(), retain() and autorelease()

简而言之,这只有两种情况你需要调用release()方法

你new一个cocos2d::CCObject子类的对象,例如CCSprite,CCLayer等。

你得到cocos2d::CCObject子类对象的指针,然后在你的代码中调用过retain方法。

下面例子就是不需要调用retain和release方法:

1CCSprite* sprite = CCSprite::create("player.png");

这里就没有更多的代码用于sprite了。但是请注意sripte->autorelease()已经在CCSprite::create(const char*)方法中被调用了,因此这个sprite将在消息循环的最后自动释放掉。

使用静态构造函数

CCSprite::create(“player.png”)是一个使用静态构造函数的例子。所以在Cocos2d-x中所有的类,除了单例,都提供了静态构造函数,这些静态构造函数包含下面4项操作:

新建一个对象

调用object->init(…)

假如初始化成功,例如,成功的找到纹理文件,那么接下来将会调用object->autorelease()。

返回这个已经被标记了autorelease的对象。

所有CCAsdf::createWithXxxx(…)这种类型的函数都有以上这些方式。

在Cocos2d-x v1.x或者更早版本里,这些方式是:

1CCSprite* sprite = CCSprite::spriteWithTexture(...)

使用这些静态构造函数,你不需要关心“new”, “delete”和“autorelease”,仅仅关心object->retain() 和 object->release()。

一个错误的例子

一个开发者报告了一个使用CCArray 并导致crash的例子

boolHelloWorld::init(){ boolbRet = false; do { ////////////////////////////////////////////////////////////////////////// // super init first ////////////////////////////////////////////////////////////////////////// CC_BREAK_IF(! CCLayer::init()); ////////////////////////////////////////////////////////////////////////// // add your codes below... ////////////////////////////////////////////////////////////////////////// CCSprite* bomb1 = CCSprite::create("CloseNormal.png"); CCSprite* bomb2 = CCSprite::create("CloseNormal.png"); CCSprite* bomb3 = CCSprite::create("CloseNormal.png"); CCSprite* bomb4 = CCSprite::create("CloseNormal.png"); CCSprite* bomb5 = CCSprite::create("CloseNormal.png"); CCSprite* bomb6 = CCSprite::create("CloseNormal.png"); addChild(bomb1,1); addChild(bomb2,1); addChild(bomb3,1); addChild(bomb4,1); addChild(bomb5,1); addChild(bomb6,1); m_pBombsDisplayed = CCArray::create(bomb1,bomb2,bomb3,bomb4,bomb5,bomb6,NULL); //m_pBombsDisplayed 是在头文件中被定义为一个 protected 变量. // <--- 我们应该添加在这里m_pBombsDisplayed->retain()方法来防止在HelloWorld::refreshData()中crash。 this->scheduleUpdate(); bRet = true; }while(0); returnbRet;} voidHelloWorld::update(ccTime dt){ refreshData();} voidHelloWorld::refreshData(){ m_pBombsDisplayed->objectAtIndex(0)->setPosition(cpp(,));}

他的错误是m_pBombsDisplayed是使用CCArray::create(…)创建的,这种创建方式是静态构造方式,这个数组被标记了autorelease。

所以这个数组会在当前消息循环的最后被CCAutoreleasePool释放掉。

cocos2dx 内存管理 防止遗忘(cocos creator内存性能优化)

当后面的消息循环调用HelloWorld::update(ccTime)的时候,m_pBombsDisplayed已经是一个野指针了,这就将引起崩溃。

为了修复这个崩溃情况,我们需要增加m_pBombsDisplayed->retain()在 m_pBombsDisplayed =CCArray::create(…);之后, 并且在 HelloWorld::~HelloWorld() 的析构函数中调用m_pBombsDisplayed->release()。

一、内存管理机制

二、图片的缓存和加载方式

三、常见的内存管理的方法:

使用AndroidStudio部署Cocos2dx-Lua项目的处理方法 背景描述最近在学习Cosox2dx-Lua的相关开发,使用了CocosCodeIDE作为开发工具。因为项目需求,我需要导入另一个我自己开发的库。因为该库包含有界面和

Cocos2dx 疯狂跑酷(CrazyRun)游戏项目解析 原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处、作者信息和本声明。否则将追究法律责任

解决cocos项目未能将插入的代码块写入pdb的问题 今天运行程序发现了这个问题,我的解决方案是:点击项目,右键属性,选择配置属性下的c/c,选择常规,把调试信息式里的程序数据库(/ZI)替换为C7兼容(/

标签: cocos creator内存性能优化

本文链接地址:https://www.jiuchutong.com/biancheng/372712.html 转载请保留说明!

上一篇:(cocs2dx)二、 利用Eclipse编译apk应用

下一篇:使用AndroidStudio部署Cocos2dx-Lua项目的处理方法(使用androidx 找不到v7)

  • 应交代扣利息税
  • 劳务派遣公司需要给员工缴纳社保吗
  • 增值税税负率是含税还是不含税
  • 税控盘的进项税在哪里申报
  • 横幅属于什么发票范围
  • 应交税费应交印花税借方有余额
  • 分支机构是不是需要设立账簿
  • 房地产企业融资存在的问题
  • 期间费用如何设置项目核算
  • 代发工资开票内容
  • 视同销售应付福利费账务处理是怎样的?
  • 团体意外伤害险是保的什么
  • 人工服务费发票
  • 开具的增值税专用发票上注明的价款为50万元
  • 没有进出口权可以做外贸吗
  • 人力成本包括哪三个方面
  • 网店提现要多久能到账
  • 年终奖个人所得税缴纳标准
  • 小规模可以接收专票吗现在
  • 上市公司的股份可以转卖吗
  • 电脑蓝屏修复方法是什么
  • 什么是文件扩展名dws
  • NEC笔记本电脑开机启动热键
  • windows7如何格式化恢复出厂设置
  • 员工的餐费补助怎么算
  • icons是什么文件夹
  • php获取中文字符串长度
  • 其他应付款余额在借方表示什么意思
  • 转让土地需要办什么手续
  • 同一控制下控股合并在合并日合并报表编报正确的有
  • 职工福利费用怎么入账
  • 浅谈php中变量的使用情况
  • Stable Diffusion - API和微服务开发
  • vue axios.all
  • opencv几何变换
  • halt关机命令
  • 织梦栏目内容不显示
  • 自产产品用于福利要交增值税吗
  • 银行承兑汇票记入会计科目
  • 应收账款扣款会计处理
  • 安装mysql5.1的步骤和方法
  • SQL中print、sp_helptext的限制与扩展
  • 出纳开的收据找不到了怎么办
  • MySQL Replace INTO的使用
  • 对方开给我的专票,我要报税吗?
  • 交易性金融资产公允价值变动怎么算
  • 年底计提坏账收回一部分怎么处理
  • 小额贷款行业新规
  • 去年亏损今年盈利同比怎么算
  • 行政事业单位拨付给企业的财政补助款用交增值税吗
  • 固定资产全套账务处理2021
  • 异地工程开票要注意什么手续
  • 采购业务 货物收到 发票收到
  • 政府无偿划拨土地如何摊销
  • sqlserverssms
  • 一个 sql 查询很慢,从哪些地方进行优化?
  • sql server的修改语句
  • sql有没有返回上一步
  • XP系统网上邻居不见了有哪些找回方法
  • fedora安装中文语言包
  • windows模拟
  • win8系统怎么做系统
  • dropbox app
  • centos怎么设置密码
  • vmware中安装centos7
  • win7玩csgo掉帧怎么办
  • win7怎么修改开机启动
  • JavaScript中的变量名不区分大小写
  • Open quote is expected for attribute "name" associated with an element type "item".
  • unity3d 脚本
  • javascript要怎么学
  • 有哪些比较好的android的框架
  • Python的collections模块中namedtuple结构使用示例
  • 河北电子税务局手机app
  • 湖南税务局发票查询
  • 如何提升基层党建质量
  • 无锡车辆购置税缴纳地点
  • 税费银联缴款
  • 官方客服热线人工台电话
  • 福建农村社保一个月可以拿多少钱
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设