原文链接: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. python --商品规格--表结构设计

    商品规格表结构设计 商品规格包括规格组合.规格项,规格项为规格组的成员. 规格组 |-规格项:规格值 |-规格项:规格值 规格组 |-规格项:规格值 |-规格项:规格值 同一类商品的规格相同. 方案一 ...

  2. 1ink 与 @import 的区别

    1ink与@import的区别 目录 1ink与@import的区别 差别1:归属关系的差别 差别2:加载顺序的差别 差别3:兼容性的差别 差别4:使用dom控制样式时的差别 1ink与@import ...

  3. 学生成绩管理系统3.0(JSP+Servlet+MySQL)

    源代码:戳这里! (2019-01-08 更新 惊讶于这么久了还有人看这个项目 于是把代码传到 github 了(辣鸡CSDN) https://github.com/G-lory/StudentAc ...

  4. mysql 开发进阶篇系列 24 查询缓存下

    一. 查询缓存 1.开启缓存 [root@xuegod64 etc]# vim my.cnf 设置了缓存开启,缓存最大限制128M,重启服务后,再次查询 -- 开启查询缓存后 SHOW VARIABL ...

  5. 深入JAVA注解(Annotation):自定义注解 (转)

    原文出自:http://blog.csdn.net/yjclsx/article/details/52101922 一.基础知识:元注解 要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义 ...

  6. 自己动手实现java数据结构(一) 向量

    1.向量介绍 计算机程序主要运行在内存中,而内存在逻辑上可以被看做是连续的地址.为了充分利用这一特性,在主流的编程语言中都存在一种底层的被称为数组(Array)的数据结构与之对应.在使用数组时需要事先 ...

  7. Deep Reinforcement Learning: Pong from Pixels

    这是一篇迟来很久的关于增强学习(Reinforcement Learning, RL)博文.增强学习最近非常火!你一定有所了解,现在的计算机能不但能够被全自动地训练去玩儿ATARI(译注:一种游戏机) ...

  8. Python机器学习笔记:利用Keras进行分类预测

    Keras是一个用于深度学习的Python库,它包含高效的数值库Theano和TensorFlow. 本文的目的是学习如何从csv中加载数据并使其可供Keras使用,如何用神经网络建立多类分类的数据进 ...

  9. AD预测论文研读系列1

    A Deep Learning Model to Predict a Diagnosis of Alzheimer Disease by Using 18F-FDG PET of the Brain ...

  10. 单例模式写MySQL model类,简单的增、删、改、查

    单例模式的用途,可用于数据库操作 <?php Class Db { static private $whe;//条件 static private $tab;//表名 static privat ...