原文链接:http://blog.sina.com.cn/s/blog_4057ab6201018y4y.html

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,便会调用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* createObjX(){
    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的理解的更多相关文章

  1. 对cocos2d 之autorelease\ratain\release的理解

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

  2. 浅谈cocosd之autorelease\retain\release的理解

    三种情况,引出问题:   1) new出来的对象需要释放,而释放时,如果有其他人引用了这个对象,再次使用这个对象时,则会出现野指针情况. ==> 于是出现了引用计数的释放管理机制. 2) 对于一 ...

  3. cocos2d-x学习知识点记录

    环境搭建 http://4137613.blog.51cto.com/4127613/751149 Cocos2d-x初探,HelloWorld解读 http://www.cnblogs.com/Ke ...

  4. autorelease基本概念

    // //  main.m //  01-autorelease基本概念 // //  Created by apple on 14-3-18. //  Copyright (c) 2014年 app ...

  5. Objective-c中autorelease的释放时机

    如果你使用过MRR,autorelease这个关键字应该是太熟悉了,每次在我们生成一个新的对象返回时,都需要向这个对象发送autorelease消息,目的是为了延时释放创建的对象.那到底是在什么时候, ...

  6. iOS基本内存管理:autorelease和autoreleasepool

    1.autorelease 基本用法 对象执行autorelease方法时会将对象添加到自动释放池中 当自动释放池销毁时自动释放池中所有对象作release操作 对象执行autorelease方法后自 ...

  7. autorelease方法

      基本用法: 1,autorelease 方法会返回对象本身 2,调用完autorelease方法后,对象的计数器不变 2,autorelease 会将对象放到一个自动释放池中 3,当自动释放池被销 ...

  8. Autorelease机制讲解

    Autorelease机制是在iOS内存管理中的一员.在MRC中,是通过调用[obj autorelease]来延迟内存释放:在ARC中,我们已经完全不需要知道Autorelease就能很好地管理好内 ...

  9. iPhone开发过程中调试多次Release问题 message sent to deallocated

    初级:第一步   为程序添加符号断点 malloc_error_break  方法如下. 目标效果:让程序崩溃时跳转到出错到那一行.但是往往达不到这个效果.不行就继续往下看. At times, wh ...

随机推荐

  1. MySQL-Cluster 和主从(Master,Slave)搭建总结

    双主互备,主从 什么是双主 MultiSource 多源复制 原理及流程图 主要步骤 1,在 Master Server 上开启 bin log 日志 和 设置 server-id  :(在my.cn ...

  2. 命令行下查看python和numpy的版本和安装位置

    命令行下查看python和numpy的版本和安装位置 1.查看python版本 方法一: python -V 注意:‘-V‘中‘V’为大写字母,只有一个‘-’ 方法二: python --versio ...

  3. Spring MVC & Boot & Cloud 技术教程汇总(长期更新)

    昨天我们发布了Java成神之路上的知识汇总,今天继续. Java成神之路技术整理(长期更新) 以下是Java技术栈微信公众号发布的关于 Spring/ Spring MVC/ Spring Boot/ ...

  4. 可以用软连接的方式解决linux内存空间不足的问题

    突然提示说/var空间满了,然后接着系统卡死,最后彻底没辙,重启试试,没想到提示什么系统错误,请联系管理员之类的提示语,也进不去登陆界面啥了.之后用其他电脑连接SSH用root账号访问. # cd / ...

  5. Screen会话命令 Linux

    由于经常在服务器上运行程序,本地不可能一直和服务器保持连接,而且如果本地和服务器的连接断开,在服务器上运行的程序将会终止,为了,查找了一些网络资料,发现screen 会话命令可以保持本地和服务器断开后 ...

  6. 用RIPv2实现网络区域的互通

    1.动态路由的分类: DV协议:距离矢量协议 距离矢量:路由器只能够知道邻居路由的信息 LS协议:链路状态协议 链路状态:路由器能够知道所在协议内的所有信息 RIP协议的全程是:路由信息协议(DV协议 ...

  7. git第七节---git merge和git rebase

    # git merge和git rebase 都可以进行分支合并 #git merge 合并后保留记录两个分支的记录 #git rebase合并后会展示成一个分支的记录,另一个分支的提交实际生成了一个 ...

  8. Spring的第三天AOP之xml版

    Spring的第三天AOP之xml版 ssm框架 spring  AOP介绍 AOP(Aspect Oriented Programming),面向切面编程.它出来的目的并不是去取代oop,而是对它的 ...

  9. IDEA配置maven(配置阿里云中央仓库)

    前言 idea配置maven后如果不修改中央仓库地址创建maven则出奇的慢,不管你用MyEclipse还是idea都慢的不要不要的,实在不能忍受. 这种条件下发现一个阿里云中央仓库来点福利,有福利了 ...

  10. Yapi学习笔记

    . 下载源码:https://github.com/YMFE/yapi 2. 安装MongoDB数据库,下载地址:链接:https://pan.baidu.com/s/1bZKlcy 密码:ah3n ...