对cocos2d 之autorelease\ratain\release的理解

对cocos2d 之autorelease\ratain\release的理解,第1张

概述看了上面博客中对autorelease的见解,对autorelease有了更深入的了解。但是还不是很理解,于是又看了代码。一开始对autorelease的“自动释放”的印象总是挥之不去。总是往java那样的完全自动释放那方面靠,于是第一感觉就错了。 以下仅针对 cocos2dx分析。 前言: 三种情况,引出问题       new出来的对象需要释放,而释放时,如果有其他人引用了这个对象,再次使用这 看了上面博客中对autorelease的见解,对autorelease有了更深入的了解。但是还不是很理解,于是又看了代码。一开始对autorelease的“自动释放”的印象总是挥之不去。总是往java那样的完全自动释放那方面靠,于是第一感觉就错了。
以下仅针对 cocos2dx分析。 前言: 三种情况,引出问题 new出来的对象需要释放,而释放时,如果有其他人引用了这个对象,再次使用这个对象时,则会导致无效指针报错。 于是有了引用计数的施放管理机制。 对于一个返回对象指针的方法。你若不看文档不看内部代码,你无法知道返回的这个指针需不需要你来释放。同样的对于将一个指针作为参数给一个方法后,你为犹豫我能不能施放这个指针。因为你不知道这个方法内部会不会将你的指针施放。 于是有了谁拥有谁施放的施放管理思想。
使用了上述管理机制和思想后,有些特定情况。比如方法内新建一个对象,然后返回对象时,按照谁拥有谁施放。对象是在方法内部新建的,方法退出前不再拥有,所以要在方法退出前释放。但是又要在退出时返回该对象。先返回还是先释放都是不对的。。。 于是就有了autorelease。 1、release 和retain是配套的,释放管理是通过引用计数。 每一个CCObject对象都有一个引用计数。retain()时引用计数+1,release()则-1.在release之后,若引用计数为0,便会调用delete this; 真正的释放自己的内存。 CCObject新建的时候,引用计数默认为1. 2、release和retain的使用的指导思想是,谁拥有谁施放。 对于一个需要释放的变量。他的生命中通过新建、传递参数、方法返回值出现在各种地方,然而只有有人需要长期存储他的引用时,即想要拥有他,才应该调用retain()。释放时则秉着“谁retain谁施放”,retain和release的调用次数要配套。 ------------------------------------------------------ voID class IhaveObjHandler() { public: ObjX* objHandler; static voID iWantObjX(objX* o){ objHandler = o; // 位置2 objHandler->retain(); } IhaveObjHandler(){ objHandler = NulL; } ~IhaveObjHandler(){ if(objHandler != NulL){ objHanlder->release(); } } }
voID dispatchObjX(){ ObjX* obj = new ObjX(); // 位置1 IhaveObjHandler:: iWantObjX( obj ); obj->release(); } ------------------------------------------------------ 示例中:需要释放管理的对象是 ObjX ,他在位置1新建,在位置2被传入到 IhaveObjHandler。 位置1:因为obj新建时引用计数为1,而我( dispatchObjX方法 )是不需要ObjX对象的,所以当我把他传给 IhaveObjHandler 之后,我便释放他。 位置2:IhaveObjHandler 里需要保存 ObjX的引用, 于是我( IhaveObjHandler类 )调用retain()。当我不需要他,想要把他释放的时候调用release(). 在释放的时候,注意自己retain几次,只能释放几次,不能过多释放。 3、autoreleas是一个特殊的release,即延后释放。 对比上面的 dispatchObjX方法 ------------------------------------------------------ ObjX* create ObjX(){ ObjX* obj = new ObjX(); obj->autorelease(); //位置3 如果改成 obj->release();则obj的引用计数为0,会被释放。 return obj ; } 上面示例是一个产生新对象的方法。经常会用到,如果按照上述的释放管理思想,如位置3的注释写的那样。会在方法返回之前被释放。于是有了autorelease。 autorelease其实只是为obj设置一个标记,延后释放。在之后的某一时刻,对obj的autorelease标记做处理(即释放)。上面示例中autorelease不是立即减少obj引用计数,则方法可以安全return obj;。 4、autoRelease实现原理的小细节 关键字CCautoreleasePool autorelease的对象会加入到从池中,最迟会在每个主循环结束前释放。 池是用栈形式管理的。在适当情况下新建一个自动释放池,加入到栈中。所有要释放的对象都会加入到当前栈顶的这个池中,在特定情况(如每次主循环结束前),将池出栈。出栈时,做一些释放池中对象的处理。 当CCObject释放时,如果该对象仍在自动释放池中,则从池中删除自己。 同一个对象多次autorelease()的话,会被多次加入池中。 池中对象存储结构是CCMutableArray,也就是vector. 5、 使用autorelease的好处
1、new出来的对象的释放问题解决了。符合谁拥有谁释放的原则。 2、可以避免频繁申请/释放内存 //ttun注:(没想出来,是什么意思
6、其实autorelease并没有那么好用 综上,autorelease只不过解决了前言中及第三条说的引用计数的那个使用上的问题。对于引用计数本质没有太大改变。 我们依旧要很 小心小心小心的注意释放对象的引用计数的变化。如果引用计数乱了一个的话,会导致报错。而且一旦因引用报错后,一般情况你是无法立即知道是哪里的引用除了问题。 另外, 使用了引用计数的话,释放对象时别用delete,而使用release()。 总结

以上是内存溢出为你收集整理的对cocos2d 之autorelease\ratain\release的理解全部内容,希望文章能够帮你解决对cocos2d 之autorelease\ratain\release的理解所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1007923.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存