现在的位置: 首页 > 综合 > 正文

关于autoRelease那点事

2012年05月04日 ⁄ 综合 ⁄ 共 1406字 ⁄ 字号 评论关闭

原文:http://www.eoeandroid.com/thread-250655-1-1.html

首先需要确定的一点是,cocos2dx采用的是引用计数的方式来管理对象的持有和释放。所谓引用计数就是说,每个对象都会有一个属性用来记录当前被几个地方引用了。在释放内存的时候会根据这个引用计数来确定是否要用delete操作符来释放这个对象占用的内存。具体见CCObeject的默认构造函数,retain和release方法。

然后再看autorelease这个方法,我不知道其他人看到这个方法的时候会做何感想,我一直都是用java的,看到这个方法第一个想法很天真,就是调用这个方法以后这个对象就被加到了一个自动化内存管理器里,就可以像在java里面一样new出来对象以后就可以不管了,会在适当的时候自动的把这个对象回收掉。但是我是个很爱追根究底的人,我知道c++本身实现并不能做到像java一样程度的自动内存管理,于是我想看看cocos2dx里面是怎么实现这么神奇的功能的。

可以看到autorelease 方法的内容是这样一句代码:
CCPoolManager::sharedPoolManager()->addObject(this);
看代码猜意思好像是说把当前对象加到一个内存池对象中。
这么说起来玄机都在CCPoolManager类了。
如果一直这么分析下去就成代码解读了,我想知道的是原理,所以不一行行的做代码分析了,只讲一下原理。
当一个对象被加到CCPoolManager里面以后这个对象的引用计数还是1(如果没有别的地方调用它的retain方法的话)。我们知道,在CCDirect的主循环方法mainLoop里面会调用CCPoolManager的pop方法,pop方法的作用其实只有一个,把当前持有的对象的引用释放,同时调用每个对象release方法(有可能被释放也有可能不释放,这取决于引用计数)。pop方法被调用以后,之前一次通过autorelease方法加到CCPoolManager中的所有对象的死活CCPoolManager都不再管了(已经放弃对这些对象的引用了)。也就是说,这个所谓的autorelease方法其实只是一个一锤子买卖,并不是我想的那样一旦调用过对象的autorelease就可以像java一样一直都可以不去管他了,所以我前面说我的想法很天真。

通过上面的分析可以总结出一个使用cocos2dx内存管理机制的一个正确规则,retain或new操作符和release必须成对出现,哪里构造的时候调了某个对象的retain方法,那在他的析构的时候就一定要调该对象的release方法。

比如我们在写代码的时候写的最多的就是把一个spriter加到layer中,实际上是加到了ccnode的一个数组中,在加入这个数组时会调用对象的retain方法,在移除这个对象时也会调用它的release方法。而在析构函数的时候layer也会调用这个数组的release方法,数组又调用它持有的所以的对象的release方法。

总的来讲,整个机制的实现还是很简单的,但是auto这种字眼很迷惑人,并不是正在的auto。所以在写代码的时候还是应该小心。

autoRelease主要是用来管理在方法作用域内通过new创建的对象的释放的,以达到这种类型的对象的内存释放能像普通定义的对象一样在方法调用一结束就进行释放。

抱歉!评论已关闭.