打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
对cocos2d?之autorelease\ratain\release的理解
http://www.cnblogs.com/MobileDevelop/archive/2010/07/19/1779138.html

看了上面博客中对autorelease的见解,对autorelease有了更深入的了解。但是还不是很理解,于是又看了代码。一开始对autorelease的“自动释放”的印象总是挥之不去。总是往java那样的完全自动释放那方面靠,于是第一感觉就错了。

以下仅针对 cocos2dx分析。

前言:
三种情况,引出问题
   new出来的对象需要释放,而释放时,如果有其他人引用了这个对象,再次使用这个对象时,则会导致无效指针报错。
    于是有了引用计数的施放管理机制。

  对于一个返回对象指针的方法。你若不看文档不看内部代码,你无法知道返回的这个指针需不需要你来释放。同样的对于将一个指针作为参数给一个方法后,你为犹豫我能不能施放这个指针。因为你不知道这个方法内部会不会将你的指针施放。
   于是有了谁拥有谁施放的施放管理思想。

   使用了上述管理机制和思想后,有些特定情况。比如方法内新建一个对象,然后返回对象时,按照谁拥有谁施放。对象是在方法内部新建的,方法退出前不再拥有,所以要在方法退出前释放。但是又要在退出时返回该对象。先返回还是先释放都是不对的。。。
    于是就有了autorelease。


1、release 和retain是配套的,释放管理是通过引用计数。
  每一个CCObject对象都有一个引用计数。retain()时引用计数+1,release()则-1.在release之后,若引用计数为0,便会调用deletethis; 真正的释放自己的内存。
   CCObject新建的时候,引用计数默认为1.

2、release和retain的使用的指导思想是,谁拥有谁施放。
   对于一个需要释放的变量。他的生命中通过新建、传递参数、方法返回值出现在各种地方,然而只有有人需要长期存储他的引用时,即想要拥有他,才应该调用retain()。释放时则秉着“谁retain谁施放”,retain和release的调用次数要配套。

------------------------------------------------------
void classIhaveObjHandler()
{
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*createObjX(){
    ObjX* obj = newObjX(); 
   obj->autorelease();  //位置3 如果改成 obj->release();则obj的引用计数为0,会被释放。
   return obj;
}
------------------------------------------------------
   上面示例是一个产生新对象的方法。经常会用到,如果按照上述的释放管理思想,如位置3的注释写的那样。会在方法返回之前被释放。于是有了autorelease。
   autorelease其实只是为obj设置一个标记,延后释放。在之后的某一时刻,对obj的autorelease标记做处理(即释放)。上面示例中autorelease不是立即减少obj引用计数,则方法可以安全returnobj;。

4、autoRelease实现原理的小细节
   关键字CCAutoreleasePool
   autorelease的对象会加入到从池中,最迟会在每个主循环结束前释放。
   池是用栈形式管理的。在适当情况下新建一个自动释放池,加入到栈中。所有要释放的对象都会加入到当前栈顶的这个池中,在特定情况(如每次主循环结束前),将池出栈。出栈时,做一些释放池中对象的处理。

   当CCObject释放时,如果该对象仍在自动释放池中,则从池中删除自己。
   同一个对象多次autorelease()的话,会被多次加入池中。池中对象存储结构是CCMutableArray,也就是vector.

5、 使用autorelease的好处

   1、new出来的对象的释放问题解决了。符合谁拥有谁释放的原则。
    2、可以避免频繁申请/释放内存//ttun注:(没想出来,是什么意思


6、其实autorelease并没有那么好用
   综上,autorelease只不过解决了前言中及第三条说的引用计数的那个使用上的问题。对于引用计数本质没有太大改变。
    我们依旧要很小心小心小心的注意释放对象的引用计数的变化。如果引用计数乱了一个的话,会导致报错。而且一旦因引用报错后,一般情况你是无法立即知道是哪里的引用除了问题。
    另外,使用了引用计数的话,释放对象时别用delete, 而使用release()。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
10个Objective
iOS ARC内存管理总结
iPhone/Mac Objective-C内存管理教程和原理剖析
iphone和Objective-C笔试题?
objective-C基础教程(第2版)-第九章笔记
[转载]iOS内存暴增问题追查与使用陷阱
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服