cocos2dx 3.2 学习篇之五(简单理解内存管理)

        自动内存管理,这个词本人第一次看到在oc编程当中看到的,一开始觉得挺神奇的,因为不了解嘛,一个学C++出生的孩子,看到这么高级的东西吓尿了。不过现在把这套机制移植到cocos2dx里面以后,看了众大神们的解释以后,发现其实也没有那么神奇。不说深入理解,至少知道个大概皮毛,知道自己 sprite->autorelease(),sprite->retain()等等在做什么了。

       C++的动态内存管理一般建议遵循谁申请谁释放的原则,即谁通过new操作符创建了对象,谁就负责通过delete来释放对象。而且new和delete必须成对出现。new很方便,即要用时候new一下对象就可以了,但是我们很难判断什么时候该去delete这个对象。可以一个对象被多个地方使用,如果一个地方用完了这个对象以后,觉得没用了,就把这个对象给释放了。但是其他地方却仍然引用这个对象,这样你就把别人用的这块公共区域给释放掉了,别人还怎么用啊! 所以!!!为了解决这个问题,聪明的人类用计数器的方法来统计有多少地方用了这个对象。

      以下是我个人理解+适当比喻,方便大家理解哈 :  

     我们把在堆上 开辟 空间比喻做 租房子吧,new操作呢对应就是 拿到房门钥匙,可以进入房门, 而delete对应的就是房间已经不要租了,可以把钥匙还给房东了(如果不操作这个后果很严重,房东以为你续租,不租给别人,你又不用,白白浪费了很多资源)。 那计数器其实就是有多少人要用这个房间,我们简化租房中间过程,假设如果一个人要用这个房间就是一直呆在房间里面,走出房间了就代表已经用完房间,不要用房间了!这样的话,我们就可以把计数器简单认为是在房间的人数量!这样就很显而易见,当房间里面没人了的时候,即计数器为 0 的时候,我们就可以把房门钥匙还给房东了。不要租房间了,即这个时候我们就可以把我们申请的动态空间还给堆了。  

     但是!!!这边细心的程序猿一定会发现!这个有bug,在房东给你钥匙后的一小段时间里,房间里怎么可能会有人!所以刚刚交给你钥匙的瞬间,不就已经同时已经退还了房间了嘛!!

当然不会,要不然人家也不好意思开发这个自动管理内存模块了。

       好,上面我们用租房子的比喻解释清楚了自动内存管理机制,接下来我们回到现实,回到编程生涯。首先为了不让系统自己一下子就把刚刚分配的空间自动回收回去!我们在创建的时候,默认把计数器设置为1  ,但是有个问题,实际这个时候没有任何地方引用到这个对象,我们必须把这个平白无辜多出来的东西在适当的时候给减掉。这个 1 必须减掉!但是不是刚刚生成的现在,在cocos2dx采用的是在这一帧结束的时候。而这个在这一帧结束的去减 1 的操作并不是平白无故就会给你做的,他是需要你去给予代码的! 这个对应的代码就是  sprite->autorelease();

可能有些人就要困惑了!!!  你说错了!!就连cocos2dx的自带hello world代码都没->autorelease()操作呢!!为什么!!! 

  好,上代码为证!

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    //创建一个空白场景
    auto scene = Scene::create();
    
    // 'layer' is an autorelease object
    //创建一个helloWorld图层,蹦添加到空白场景中。
    auto layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}


        这段代码就充分表明!根本就没有autorelease()这个!!!  


       好~~~这边先解释以下,大家可以选中create()函数,跳入他的实现代码。可能需要跳两次。之后你就会神奇发现这段代码:

Scene* Scene::create()
{
    Scene *ret = new Scene();
    if (ret && ret->init())
    {
        ret->autorelease();
        return ret;
    }
    else
    {
        CC_SAFE_DELETE(ret);
        return nullptr;
    }
}

    好,上面代码就可以证明为所说的,在创建新物件时候,会自带一个autorelease()函数。

   但是!!并不是所有时候,系统都会给你自动添加autorelease()的!在某些时候是需要我们自己去使用,比如你去申请一个新按钮选择的语法是这样的。

   首先新建一个按钮对象   Button* button = new Button(); 然后你给他添加各种状态下的纹理,然后!!!这个必须的时刻,你就要去autorelease()了。。。原因很简单,其实就是你自己用代码去实现crete()函数,crete()里面有autorelease,你当然也要去添加啦。


   上面已经基本解释清楚了自动内存管理的基本内容了,那有些人有奇葩需求,比如说,我现在创建好按钮,可能我n帧以后才会知道谁要引用它,我们上面也说了,这一帧结束会被autorelease()掉,如果这一帧没人引用它就被自动销毁了,那我n帧以后再去引用不就会产生找不到指定内存了么!!!  

    不要慌,聪明的人类总有办法的,就连飞船都怕出故障,设置的自动制动和手动制动。cocos2dx也当然有手动内存干预管理啊,我既然这一帧没人引用它,我就让它计数器多+1(->retain())么,然后就始终不会变0 了么。。因为暂时没人引用它,自然也不会产生-1 的指令嘛,这样自然就可以等到来引用它的对象了。  但是千万记得,我们+1->retain()了不是白白加的,我们还得手动去 -1(->release()),这样的话这个对象就不会永久无法删除了。自然不会内存泄漏了。

   

   还有一个一直忘记讲的,自动内存管理的管理的对象是 Ref ,即老版本的 CCobject,众所周知,所有的物件都是继承于这个基类的。


   关于自动内存管理,本人的理解基本就是这样了,分享给大家。可能理解有偏差,欢饮大家指出错误,让我正确的成长哈~~~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值