1.cocos2dx内存管理和CCArray,CCMenuItem

1 C++内存管理


A
栈上的空间


自生自灭,不用管理


B
堆上的空间


手动new,手动delete,否则产生内存泄漏

2
内存管理的难处


管理原则,谁申请谁释放

3
内存的智能管理

主要有两种实现智能管理内存的技术,一种是引用计数,一是垃圾回收。

引用计数:通过给每个对象维护一个引用计数器,记录该对象当前被引用的次数。当对象增加一次引用时,计数器加1;而对象失去一次引用时,计数器减1;当引用计数为0
时,标志着该对象的生命周期结束,自动触发对象的回收释放。引用计数解决了对象的生命周期管理问题,但堆碎片化和管理烦琐的问题仍然存在。

垃圾回收:它通过引入一种自动的内存回收器,试图将程序员从复杂的内存管理任务中完全解放出来。它会自动跟踪每一个对象的所有引用,以便找到所有正在使用的对象,然后释放其余不再需要的对象。垃垃圾回收器通常是作为一个单独的低级别的线程运行的,在不可预知的情况下对内存堆中已经死亡的或者长时间没有使用过的对象进行清除和回收。

4 cocos2dx内存管理

A
手动管理

Cocos2dx采用工厂方法创建对象,所有生成的对象均在堆上,所以Cocos2dx采用了引用计数的方法管理内存。具体实现:

B  
案例说明:


T09Memory.h


#ifndef
_T09Memory_

#define
_T09Memory_

#include
"cocos2d.h"

USING_NS_CC;

class
T09Memory :public
CCLayer

{

public:

static
CCScene *
scene();

CREATE_FUNC(T09Memory);

bool
init();

CCSprite *
spr;

void
mySchedule(float
dt);

};

#endif


T09Memory.cpp


#include
"T09Memory.h"

CCScene *
T09Memory::scene()

{

CCScene *scene
= CCScene::create();

T09Memory *layer
= T09Memory::create();

scene->addChild(layer);

return
scene;

}

bool
T09Memory::init()

{

CCLayer::init();

spr =
new
CCSprite();

//CCLog("retain count %d", spr->retainCount());

spr->retain();
//引用计数加1

CCLog("use
spr->retatin : retain count %d",
spr->retainCount());

//spr->release();

//CCLog("retain count %d", spr->retainCount());

spr->init();

spr->release();

//autorelease()也release了但是不一定就释放了,而是遵循延时释放

spr->autorelease();   
//延时释放

//CCLog("retain count %d", spr->retainCount());

addChild(spr);  
//这里引用,这里引用加1

CCLog("retain
count %d",
spr->retainCount());

//通过下面可以证明上面已经释放内存了

schedule(schedule_selector(T09Memory::mySchedule),2);

return
true;

}

void
T09Memory::mySchedule(float
dt)

{

CCLog("retain
count %d",
spr->retainCount());

}


运行结果:

C
 retain()本质


autorelease()本质(延迟释放内存)

5 CCArray

A
类关系图

B
 CCArray继承自CCObject,而非CCNode,没有办法加到渲染树中去,但是参加了内存托管。所以应该手动处理。

示例:


Array = CCArray::create();

Array->retain();

CCSprite *spr = CCSprite::create();

array->addObject(spr);

CCMenuItem *item = CCMenuItemImage::create(“closeNormal.png”

“CloseSelected.png”,

this,

menu_selector(T09Memory::menuCallBack) );

CCMenu * menu = CCMenu::create(item,NULL);

addChild(menu);


Void T09Memory::menuCallBack(CCObject *obj){

//获得array中的第一个值

array->objectAtIndex(0);

}


例外中的例外


void T09Memory::onExit(){

array->release();

}

C CCArray的案例:


T09Memory.h


#ifndef
__T09Memory_H__

#define
__T09Memory_H__

#include
"cocos2d.h"

USING_NS_CC;

class
T09Memory :public
CCLayer

{

public:

static
CCScene *
scene();

CREATE_FUNC(T09Memory);

bool
init();

CCSprite *
spr;

void
menuCallback(CCObject
* obj);

CCArray *array;

void
onExit();

};

#endif


T09Memory.cpp


#include
"T09Memory.h"

CCScene *
T09Memory::scene()

{

CCScene *scene
= CCScene::create();

T09Memory *layer
= T09Memory::create();

scene->addChild(layer);

return
scene;

}

bool
T09Memory::init()

{

CCLayer::init();

array = CCArray::create();

array->retain();

spr =
CCSprite::create("CloseNormal.png");

CCSprite *
spr2 =
CCSprite::create("p_3_01.png");

array->addObject(spr);

array->addObject(spr2);

//添加一个精灵

addChild(spr);

//通过下面的方式实现鼠标点击上去后图片切换的效果

CCMenuItem *
item =
CCMenuItemImage::create(

"CloseNormal.png",

"CloseSelected.png",

this,

menu_selector(T09Memory::menuCallback));

CCMenu *
menu =
CCMenu::create(item,
NULL);

//添加CCMenuItem条项

addChild(menu);

return
true;

}

void
T09Memory::menuCallback(CCObject
* obj)

{

array->objectAtIndex(0);

//下面的一句将CCArray中的第二个参数去除来了

CCSprite *
spr = (CCSprite
*)array->objectAtIndex(1);

spr->setPosition(ccp(100,200));

addChild(spr);

}

//在层退出的时候调用

void
T09Memory::onExit()

{

//降引用计数减1

array->release();

}


运行结果:

点击前:

点击后:



时间: 2024-10-06 00:10:47

1.cocos2dx内存管理和CCArray,CCMenuItem的相关文章

cocos2dx 内存管理

cocos2dx的内存管理移植自Objective-C, 对于没有接触过OC的C++开发人员来说是挺迷惑的.不深入理解内存管理是无法写出好的C++程序的,我用OC和cocos2dx也有一段时间了,在此总结一下,希望对想用cocos2dx开发游戏的朋友有所帮助. C++的动态内存管理一般建议遵循谁申请谁释放的原则,即谁通过new操作符创建了对象,谁就负责通过delete来释放对象.如果对象的生命周期在一个函数内,这很容易做到,在函数返回前delete就行了.但一般我们在函数中new出来的对象的生命

iOS内存管理和malloc源码解读

0. iOS内存基本原理 在接触iOS开发的时候,我们都知道“引用计数”的概念,也知道ARC和MRR,但其实这仅仅是对堆内存上对象的内存管理.用WWDC某Session里的话说,这其实只是内存管理的冰山一角. 在内存管理方面,其实iOS和其它操作系统总体上来说是大同小异的,大的框架原理基本相似,小的细节有所创新和不同. 和其它操作系统上运行的进程类似,iOS App进程的地址空间也分为代码区.数据区.栈区和堆区等.进程开始时,会把mach-o文件中的各部分,按需加载到内存当中. 而对于一般的iP

cocos2dx内存管理

cocos2dx基于引用计数管理内存,所有继承自CCObject的对象都将获得引用计数的能力,可通过调用retain成员函数用于引用计数值,调用release减少引用计数值,当计数值减为0时销毁对象. cocos2dx的对象管理是树形结构的,可通过调用父亲节点的addChild成员函数将一个子节点对象添加到父节点中,当子节点被添加到父亲节点中,子节点的引用计数值加1,如果通过removeChild将子节点从父节点中移除子节点的引用计数值减1.当父节点被销毁时,会遍历其所有的子节点,将其子节点的引

cocos2d-x 源码分析 : Ref (CCObject) 源码分析 cocos2d-x内存管理策略

源码版本来自3.x,转载请注明 cocos2d-x 源码分析总目录: http://blog.csdn.net/u011225840/article/details/31743129 1.Ref,AutoreleasePool,PoolManager Ref中包含了一个叫referenceCount的引用计数,当一个Ref类的变量被new的时候,其referenceCount的引用计数被置为1. 其中有三个重要的操作,retain,release,autorelease,下面源码分析时会详细说明

Cocos2d-x内存自动释放机制--透彻篇

首先在架构里面需要明白,如果使用new创建对象的话,我们需要自己释放内存,如果直接用引擎提供的警静态方法,我们可以不做内存管理,引擎自动处理,因为引擎背后有一个自动释放池.通过查看源码可以知道,每个静态方法都会调用autorelease()方法.如果我们需要引擎自动释放一个对象,创建后可以调用该对象的autorelease()(前提是该对象所属类继承自CCObject),该方法会把当前对象放入自动释放池中,每次帧过渡时都会去遍历检查是否可以释放掉该对象的内存. 源码如下: // 创建一个精灵对象

JVM内存管理和JVM垃圾回收机制

JVM内存管理和JVM垃圾回收机制(1) 这里向大家描述一下JVM学习笔记之JVM内存管理和JVM垃圾回收的概念,JVM内存结构由堆.栈.本地方法栈.方法区等部分组成,另外JVM分别对新生代和旧生代采用不同的垃圾回收机制. AD: 你对JVM内存组成结构和JVM垃圾回收机制是否熟悉,这里和大家简单分享一下,希望对你的学习有所帮助,首先来看一下JVM内存结构,它是由堆.栈.本地方法栈.方法区等部分组成,结构图如下所示. JVM学习笔记 JVM内存管理和JVM垃圾回收 JVM内存组成结构 JVM内存

Cocos2d-x内存管理

Cocos2d-x内存管理浅解 1.首先我们知道内存管理分为c++自身管理机制以及Cocos2d-x内存管理机制.在c++中,内存分为堆区.栈区.静态存储区(全局存储区).常量存储区.自由存储区. 主要先说一下堆区和栈区.堆区主要由new和malloc分配,new与delete,malloc与free成对出现,保证内存的分配与回收.堆内存分配地址是逐渐增大的,这一点与栈区相反,我们都知道栈是先进后出,所以栈的存储方向是内存地址逐渐减小的.栈中的内存也是系统自动回收的,这个我们不需要考虑自己管理内

转 cocos2dx内存优化 (之二)

一.cocos2dx之如何优化内存使用(高级篇) 本文由qinning199原创,转载请注明:http://www.cocos2dx.net/?p=93 一.内存优化原则 为了优化应用内存,你应该知道是什么消耗了你应用的大部分内存,答案就是Texture(纹理)!它几乎占据了90%的应用内存.那么我们应该尽力去减小我们应用的纹理内存使用,否则我们的应用进程可能会被系统杀死. 为了减少内存警告,这里我们给出两个普遍的关于cocos2dx游戏内存优化的指导原则. 1)了解瓶颈,然后解决掉 什么样的纹

帝国塔防2充值界面闪退BUG修复总结(cocos2dx内存管理机制)

游戏充值界面老是闪断,debug调试断点总是断在比较深的位置,也看不出哪里出错. 后来有一次断点断在了程序创建一个提示图片的地方,于是检查代码发现了问题. 修改之前的错误代码: 1.创建提示的代码: m_loading = new NetLoading(this, callfunc_selector(IapShopLayer::downingUpdate)); // m_loading 引用计数为1 m_loading->setPosition(ccp(1139/2.0f, 640.0f/2.0