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()本质

D  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);

}

C  例外中的例外

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();

}

运行结果:

点击前:

点击后:

 

 

 

 

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

涂作权的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值