cocos2d-x内存管理(2)

好了,内存回收池我觉的我已经说清楚了。下面我们来看一下,通常我们的代码都是怎么写的,来看看这个自动回收机制怎么就做到自动回收了!

cocos2d-x  内存管理(2) - 程序猿人 - coder


首先我们需要分析一下上边的代码,调用了create工厂方法以后,内部的实现是先new一个CCSprite的对象,这个时候引用计数加1,然后调用autorelease方法,将这个对象放到了自动回收池中,因为这一帧还没有结束,当然引用计数就还是1,所以打印的结果就是1,当我们调用addChild的时候,传入这个CCSprite对象,这个时候在当前层接受了这个对象以后会把它的引用计数加一,表明当前层正在使用这块内存空间,所以现在的retain就是2了。当这一帧结束的时候自动回收池会将对象的引用计数-1,所以现在就只有CCLayer在引用这个对象了,当CCLayer析构的时候,它会调用这个对象的release方法,这个时候当然就会删除了这个CCSprite对象了。所以什么是自动回收机制呢,自动就是在这一帧结束的时候将对象开始new的时候加的那个引用计数减掉,而让引擎中持有对象引用的其他类去管理这个对象,当持有者析构的时候就删除引用,引擎中的类负责retain和release,这个也算是自动吧!下面我们通过俩个例子来理解一下这个内存管理机制。

cocos2d-x  内存管理(2) - 程序猿人 - coder

 

好了,运行程序我们会发现程序崩溃了,我们来分析一下。当我们创建了CCSprite对象的时候引用计数为1,并且该对象被放到了内存回收池中,在这一帧以后就会release对象一次,这个时候引用计数为0的对象当然就被释放了,我们按下按钮去调用这个对象,内存已经释放掉了,程序能不崩溃吗?下面我们来将代码改成如下的这样,看看效果。

1 this->m_sprite = CCSprite::create("HelloWorld.png");
2     CCLog("%d",this->m_sprite->retainCount());
3     this->m_sprite->retain();
4     CCLog("%d",this->m_sprite->retainCount());

这个时候运行起来程序,在按钮的函数调用的时候你会看到输出的引用计数都是1,因为我们已经手动的retain了一下这个对象,虽然自动回收池将它release了一下,但是它的引用计数任然为1。既然我们retain了,所以在层析构的时候记得要release啊。这样内存才不会泄露!还有一个就是CCArray的例子,下面来看一下。

1 bool HelloWorld::init()
2 {
3     bool bRet = false;
4     do
5     {
6         //
7         // 父类初始化
8         //
9  
10         CC_BREAK_IF(! CCLayer::init());
11         CCSprite* bomb1 = CCSprite::create("CloseNormal.png");
12         CCSprite* bomb2 = CCSprite::create("CloseNormal.png");
13         CCSprite* bomb3 = CCSprite::create("CloseNormal.png");
14         CCSprite* bomb4 = CCSprite::create("CloseNormal.png");
15         CCSprite* bomb5 = CCSprite::create("CloseNormal.png");
16         CCSprite* bomb6 = CCSprite::create("CloseNormal.png");
17  
18         addChild(bomb1,1);
19         addChild(bomb2,1);
20         addChild(bomb3,1);
21         addChild(bomb4,1);
22         addChild(bomb5,1);
23         addChild(bomb6,1);
24  
25         m_pBombsDisplayed = CCArray::create(bomb1,bomb2,bomb3,bomb4,bomb5,bomb6,NULL);
26  
27         this->scheduleUpdate();
28  
29         bRet = true;
30     while (0);
31  
32     return bRet;
33 }
34  
35 void HelloWorld::update(ccTime dt)
36 {
37     refreshData();
38 }
39  
40 void HelloWorld::refreshData()
41 {
42     m_pBombsDisplayed->objectAtIndex(0)->setPosition(cpp(100,100));
43 }

其实这个原理和上边的例子是差不多的,我们创建了一个CCArray的对象,这个时候同样是没有添加到其他的层中的,所以在这一帧结束的时候就会将它的引用计数减1变成0,所以,再次使用的时候肯定就会出错了!在使用cocos2dx的内存管理的时候如果我们是通过工厂的方法创建的,并且add到了其他的层中的时候这个时候我们多数是不用担心的,但是如果你是通过new的方法创建的CCObject子类的对象,这个时候记住要在析构的时候release这个对象,如果在使用过程中你retain了对象,同样记住要release。本人总结的是,当我们调用函数传递CCObject子类对象的时候,在接受的时候我们都应该去retain一下,这样代表的是我要引用这块内存空间,什么时候你不再引用这块内存空间了,就release一下。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值