前言:
三种情况,引出问题
    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的理解

    原文链接:http://blog.sina.com.cn/s/blog_4057ab6201018y4y.html Objective C内存管理进阶(二):理解autorelease: http:/ ...

  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机制讲解

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

  5. objective-C 的内存管理之-自动释放池(autorelease pool)

    如果一个对象的生命周期显而易见,很容易就知道什么时候该new一个对象,什么时候不再需要使用,这种情况下,直接用手动的retain和release来判定其生死足矣.但是有些时候,想知道某个对象在什么时候 ...

  6. OC 知识:彻底理解 iOS 内存管理(MRC、ARC)

    1. 什么是内存管理 程序在运行的过程中通常通过以下行为,来增加程序的的内存占用 创建一个OC对象 定义一个变量 调用一个函数或者方法 而一个移动设备的内存是有限的,每个软件所能占用的内存也是有限的 ...

  7. autorelease基本概念

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

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

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

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

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

随机推荐

  1. 数据结构(11) -- 邻接表存储图的DFS和BFS

    /////////////////////////////////////////////////////////////// //图的邻接表表示法以及DFS和BFS //////////////// ...

  2. 如何杀掉当前正在执行的hadoop任务

    [root@Slave01 ~]# hadoop job -listDEPRECATED: Use of this script to execute mapred command is deprec ...

  3. 通过AopTestUtils对切面对象进行mock

    概述   当对一个切面类进行测试时,由于Spring对切面对象生成了proxy对象,此时对切面对象使用ReflectionTestUtils赋值,操作的是proxy对象,而不是真实对象,会使得赋值出问 ...

  4. freetds相关

    什么是FreeTDS  简单的说FreeTDS是一个程序库,可以实现在Linux系统下访问微软的SQL数据库! FreeTDS 是一个开源(如果你喜欢可以称为自由)的程序库,是TDS(表列数据流 )协 ...

  5. Python 网页爬虫 & 文本处理 & 科学计算 & 机器学习 & 数据挖掘兵器谱(转)

    原文:http://www.52nlp.cn/python-网页爬虫-文本处理-科学计算-机器学习-数据挖掘 曾经因为NLTK的缘故开始学习Python,之后渐渐成为我工作中的第一辅助脚本语言,虽然开 ...

  6. 【132】iPad使用相关问题

    1.想iPad中导入音乐文件,保留原音乐文件名称 [方法]需要删除音乐文件中的“标题”和“参与创作的艺术家”,直接删除的话,效率比较低,需要借助一款软件——foobar2000,选中导入的文件,然后属 ...

  7. DataTable的新建、查询、添加和修改

    详细讲解了C#开发中数据类型DataTable的使用,包括新建DataTable,查询DataTable,在DataTable里添加记录,添加 列,修改列的属性以及修改某行某列的值的方法.同时说明了将 ...

  8. C++11对象构造的改良

    [C++11对象构造的改良] C++03中一个构造函数无法构造另一个构造函数,因为A()实际上意味着生成一个临时对象,存在语音混淆.详情请看参考2. C++11中允许直接在初始化列表中调用其它的构造函 ...

  9. LDR指令的格式:

    http://blog.csdn.net/tanyouliang/article/details/6767011 LDR指令的格式: LDR{条件}   目的寄存器     <存储器地址> ...

  10. WT588D播放合成语音时出现某些语句不能正常播报的情况,经过对比其他语句,看似有点不符合逻辑。

    现象:某条语句本该播放完循环,实际确实不断循环第一个字,不能正常播放 原因:用语音合成工具合成该语句时,改了里面的默认音量,导致播放时出现液晶显示错误(感觉好像驱动不了的样子,我就是观察到这个现象才想 ...