对cocos2d 之autorelease\ratain\release的理解

前言:

三种情况,引出问题

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的理解

时间: 2024-10-29 04:18:00

对cocos2d 之autorelease\ratain\release的理解的相关文章

cocos 2dX 中的 autorelease / retain /release 用法小总结。

我们撰写代码是无法避免是要和内存打交道的,内存的使用和释放也就成为了一个问题 ,在cocos中 有如下几种使用方式. 1,autorelease  自动释放池,首先我们来看看相应的开放源码. 当我们对一个对象进行autorelease后,cocos会把这个对象放入内存池,内存池会在用户使用这个对象后自动将对象释放.自动释放池会在下一帧将对象减一,如果没有其他对象使用的话,这个内存池就被释放掉了. 但是有时候我们申请一块内存后并不会马上使用,比如不会马上就某个精灵addChild ,如果我们还是使

OC基础(十三)autorelease自动释放池

autorelease 自动释放池 autorelease是一种支持引用计数的内存管理方式,只要给对象发送一条autorelease消息,会将对象放到一个自动释放池中,当自动释放池被销毁时,会对池子里面的所有对象做一次release操作 优点:不用再关心对象释放的时间,不用再关心什么时候调用release 原理:autorelease实际上只是把对release的调用延迟了,对于每一个autorelease,系统只是把该 Object放入了当前的autorelease pool中,当该pool被

iOS基本内存管理:autorelease和autoreleasepool

1.autorelease 基本用法 对象执行autorelease方法时会将对象添加到自动释放池中 当自动释放池销毁时自动释放池中所有对象作release操作 对象执行autorelease方法后自身引用计数器不会改变,而且会返回对象本身 2.autorelease 的优点 autorelease实际上只是把对release的调用延迟了,对于每一次autorelease系统只是把该对象放入了当前的autorelease pool中,当该pool被释放时,该pool中的所有对象会被调用Relea

黑马程序员---autorelease方法

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 基本用法: 1,autorelease 方法会返回对象本身 2,调用完autorelease方法后,对象的计数器不变 2,autorelease 会将对象放到一个自动释放池中 3,当自动释放池被销毁时,会对池子里面的所有对象做一次release操作 autorelease的好处: 1>不用再关心对象释放的时间 2>不用再关心什么时候调用release autorelease的使用注意: 1&

autorelease基本概念

// //  main.m //  01-autorelease基本概念 // //  Created by apple on 14-3-18. //  Copyright (c) 2014年 apple. All rights reserved. // //内存管理原则(配对原则):只要出现了new,alloc,retain方法,就要配对出现release,autorelease //对象存入到自动释放池中,当这个池子被销毁的时候他会对池子中所有的对象进行一次release操作 //怎么把对象

release 和 drain

转载自:http://tieba.baidu.com/p/3427605546 当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池.它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息.当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放. 1. ojc-c 是通过一种"referring counting"(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引

Objective-C - autorelease详解

autorelease详解 /* 1.autorelease的基本用法 1> 会将对象放到一个自动释放池中 2> 当自动释放池被销毁时,会对池子里面的所有对象做一次release操作 3> 会返回对象本身 4> 调用完autorelease方法后,对象的计数器不变 2.autorelease的好处 1> 不用再关心对象释放的时间 2> 不用再关心什么时候调用release 3.autorelease的使用注意 1> 占用内存较大的对象不要随便使用autorelea

iOS复习笔记8:autorelease详解

一 概念 iOS在程序在运行的过程中,会创建很多个释放池,自动释放池以栈的形式存放的(先进后出). 对象调用autorelease时,会被放入栈顶的自动释放池中. 当自动释放池销毁时,会对池的所有对象发送一次release消息: 所以发送autorelease之后引用计数不会立即-1. autorelease返回对象本身. 二 实例 // Person.h @interface Person @property(nonatomic, assign) int age; @end // Person

黑马程序员-OC学习笔记之autorelease与自动释放池

---------------------- IOS开发.Android培训.期待与您交流! ---------------------- 一.autorelease autorelease与release相似,是OC中的一个对象方法.这两个方法都能把对象的引用计数器减1,但是release是一个精确的减1,对对象的操作只能在release之前进行,如果是在之后,就会出现野指针错误:而autorelease是一个不精确的引用计数器减1,当给对象发送autorelease消息时,对象就会被放到自动