ios retain release和release倒底怎么玩

转:retain和release倒底怎么玩?
retain和倒底怎么玩?
呼呼,好久没有发布教程了(小若:难得清静了,你为毛又出来吓人=&=),其实最近木头我在准备出版书籍的事情。但是貌似不太顺利,果然我还是积累不够,写书的过程压力好大,感觉写不出有趣的文字出来(小若:嗷、、、)。果然还是在博客写自由一些?嘿嘿~
最近以及最不是很近(小若:书里一定不能出现这些错误的语句,所以你才写不出来吧),不少朋友对的认识似乎有点模糊,今天我就和大家分享一下关于的知识吧
笨木头花心贡献,啥?花心?不呢,是用心~
转载请注明,原文地址:&
1.&为什么会有?
C++和不一样,有一套很方便的垃圾回收机制,当我们不需要使用某个对象时,给它赋予值即可。而了一个对象之后,不使用的时候通常需要掉。
于是,就发明了一套内存管理机制(小若:发你妹纸。。。),其实红孩儿的博客很详细地解释了的内存管理机制,我没有能力也不想重复解释。(小若:那你还写?)
Retain的意思是保持引用,也就是说,如果想保持某个对象的引用,避免它被释放,那就要调用对象的函数。(小若:为什么不就会被释放?)
2.&真正的凶手
既然旁白诚心诚意地问我,那我就光明正大地回答吧(小若:我今天没力气吐槽,好吧)。
一旦调用对象的函数,那么这个对象就被的内存管理机制给盯上了,如果这个对象没人认领,那就等着被释放吧。(小若:太久没吐槽,一时不知道吐什么好)。
3.&看代码实际点
说了这么多,还是上代码吧。
创建一个的项目,就直接拿开刀,修改函数,在最后添加一句代码:
(小若:是什么东东?)
testSprite是一个成员变量,在头文件里加上就可以了:
然后,最关键的来了,我们修改函数:
现在,运行项目,点击按钮,看看是什么情况?
(小若:报错了!)
如果大家知道怎么调试项目的话,我们在函数里断点,用调试模式运行项目,看看对象:
(小若:很正常啊,有什么特别的?)
正你妹纸啊,正!你才正!(小若:不要这么光明正大地赞我!)
我们应该能看到不少非正常数据,图中已经用红色圈圈标出来了,这代表对象被释放了,现在指向未知的位置。
这是很危险的,有时候它不会立即报错,但是在某个时刻突然崩溃!
要想解决这个问题,很简单,再次修改函数:
再次运行项目,看看还会不会报错?(小若:不会了,为什么?)
再次用调试模式运行项目,看看对象:
(小若:不正常!都是!!)
零你妹纸(小若:为什么今天你总是抢我的对白!)
这次我们看到的数据明显正常了。
4.&原理来了
好了,唠叨了一大堆,还没有进入正题。
首先,要想让对象参与内存管理机制,必须继承类(、等都继承了类)。
然后,调用对象的函数,对象就会被的内存管理机制盯上,在游戏的每一帧,内存管理机制都会扫描一遍被盯上的对象,一旦发现对象无人认领,就会将对象杀死!(小若:嗷残忍!)
如果不想让对象被杀死,那么就要调用对象的函数,这样对象就被认领了,一旦对象被认领,就永远不会被内存管理机制杀掉,是永远,一辈子。(小若:好朋友,一辈子)
但,对象一辈子都不被释放的话,那么就会产生内存泄露,你试试加载一个占内存的对象一辈子不释放,不折腾死才怪(小若:你去加载一个的对象本身就是闲的那个什么疼啊!)因此,当你不需要再使用这个对象时,就要调用对象的函数,这是和对应的。一般可以在析构函数里调用函数。
5.&实际情况
讲道理,大家都懂,但是,相信很多朋友在实际写代码的时候,还是会感觉很混乱。
比如,什么时候该?大家是不是发现,有时候不也不会报错?
其实这很简单,因为我们经常会在一个对象之后,添加到层里,如:
testSprite&=&CCSprite::create("HelloWorld.png");
this-&addChild(testSprite);
addChild函数就是导致大家混乱的凶手了,函数会调用对象的函数,为什么它要调用对象的函数呢?因为你都把对象送给它当孩子了,它当然要认领这个对象了!(小若:我懂了,嗷!)
于是,当我们把对象到时(不一定是,、都行),我们就不需要调用对象的函数了。
6.&那倒底什么时候要?
说了这么多,还是没有说清楚,什么时候要调用对象的。
很简单,当你把一个对象作为成员变量时,并且没有把对象到另外一个对象时,就需要调用函数。
7.&最后的最后
一定要记住,必须要调用了对象的函数之后,和函数才会生效,否则,一切都是徒劳。
因此,十分建议使用的方式创建对象,如:
这些就是retain表面上的知识了,至于retain源码级别的解说,请到红孩儿的博客吧,强烈推荐~
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
&2、调用对象的autoRelease函数,对象将接受Cocos2d-x的内存管理机制监控,在游戏的每一帧,内存管理机制都会扫描一遍被盯上的对象,一旦发现对象没有被引用,就会被释放。&3、如果不想被释放,那么就要调用对象的retain函数,这样对象不会被内存管理机制杀掉了。&4、当不需要再使用这个对象时,就要调用对象的release函数,这是和retain对应的。一般可以在析构函数里调用release函数。release是主动释放回收,autoRelease由系统判断回收。
阅读(6121)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_084069',
blogTitle:'cocos2dx中retain和release',
blogAbstract:'1、要想让对象参与内存管理机制,必须继承CCObject类(CCNode、CCLayer等都继承了CCObject类)。&2、调用对象的autoRelease函数,对象将接受Cocos2d-x的内存管理机制监控,在游戏的每一帧,内存管理机制都会扫描一遍被盯上的对象,一旦发现对象没有被引用,就会被释放。&3、如果不想被释放,那么就要调用对象的retain函数,这样对象不会被内存管理机制杀掉了。&4、当不需要再使用这个对象时,就要调用对象的release函数,这是和retain对应的。一般可以在析构函数里调用release函数。',
blogTag:'retain,release,cocos2dx',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:0,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}Pages: 1/2
主题 : retain与release的疑问
级别: 骑士
可可豆: 1950 CB
威望: 1950 点
在线时间: 118(时)
发自: Web Page
来源于&&分类
retain与release的疑问&&&
在C或C++中&开辟内存与释放内存是对应的&&malloc free&new&&&&delete&&而在objective C中,却是很奇怪,alloc 可以对应release&&retain也能对应release&&在一个书上例子中,有一点我不明白,发此贴,问:&&&&&&AddressCard.h &&&&&#import &Foundation/NSObject.h&&&&&&#import &Foundation/NSString.h&&&&&&&&&&&@interface AddressCard: NSObject {&&&&&&&&&NSString *&&&&&&&&&NSString *&&&&&&&&&NSString *&&&&&}&&&&&&&&&&-(AddressCard*) initWithFirst: (NSString*) f&&&&&&&&&&&&&&&&&&&&&last: (NSString*) l&&&&&&&&&&&&&&&&&&&&&email: (NSString*)&&&&&-(NSString*)&&&&&-(NSString*)&&&&&-(NSString*)&&&&&-(void) setFirst: (NSString*)&&&&&-(void) setLast: (NSString*)&&&&&-(void) setEmail: (NSString*)&&&&&-(void) setFirst: (NSString*) f&&&&&&&&&&&&&last: (NSString*) l&&&&&&&&&&&&&email: (NSString*)&&&&&-(void) setFirst: (NSString*) f last: (NSString*)&&&&&-(void)&@end&&&&&AddressCard.m &&&&&#import &AddressCard.h&&&&&&#import &stdio.h&&&&&&&&&&&@implementation AddressCard&&&&&-(AddressCard*) initWithFirst: (NSString*) f&&&&&&&&&&&&&&&&&&&&&last: (NSString*) l&&&&&&&&&&&&&&&&&&&&&email: (NSString*) e {&&&&&&&&&self = [super init];&&&&&&&&&&&&&&if ( self ) {&&&&&&&&&&&&&[self setFirst: f last: l email: e];&&&&&&&&&}&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&-(NSString*) first {&&&&&&&&&&&&&&}&&&&&&&&&&-(NSString*) last {&&&&&&&&&&&&&&}&&&&&&&&&&-(NSString*) email {&&&&&&&&&&&&&&}&&&&&&&&&&-(void) setFirst: (NSString*) f {&&&&//f的值,&&被传入&&&&&&&&&[f retain];&&&&//这个对方我能理解在开辟一次内存来存放的值&&&&&&&&&[first release];//&&&& 而赋值的第一次,first为NULL也能release?&&当然在第二次调用&& setFirst时,first不为空可以被释放,这点我看不懂&&&&&&&&&first =&&&&&}&&&&&&&&&&-(void) setLast: (NSString*) l {&&&&&&&&&[l retain];&&&&&&&&&[last release];&&&&&&&&&last =&&&&&}&&&&&&&&&&-(void) setEmail: (NSString*) e {&&&&&&&&&[e retain];&&&&&&&&&[email release];&&&&&&&&&email =&&&&&}&&&&&&&&&&-(void) setFirst: (NSString*) f&&&&&&&&&&&&&last: (NSString*) l&&&&&&&&&&&&&email: (NSString*) e {&&&&&&&&&[self setFirst: f];&&&&&&&&&[self setLast: l];&&&&&&&&&[self setEmail: e];&&&&&}&&&&&&&&&&-(void) setFirst: (NSString*) f last: (NSString*) l {&&&&&&&&&[self setFirst: f];&&&&&&&&&[self setLast: l];&&&&&}&&&&&&&&&&-(void) print {&&&&&&&&&printf( &%s %s &%s&&, [first cString],&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&[last cString],&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&[email cString] );&&&&&}&&&&&&&&&&-(void) dealloc {&&&&&&&&&[first release];&&&&&&&&&[last release];&&&&&&&&&[email release];&&&&&&&&&[super dealloc];&&&&&}&@end&&&&&main.m &&&&&#import &AddressCard.h&&&&&&#import &Foundation/NSString.h&&&&&&#import &stdio.h&&&&&&&&&&&int main( int argc, const char *argv[] ) {&&&&&&&&&NSString *first =[[NSString alloc] initWithCString: &Tom&];&&&&&&&&&NSString *last = [[NSString alloc] initWithCString: &Jones&];&&&&&&&&&NSString *email = [[NSString alloc] initWithCString: &&];&&&&&&&&&AddressCard *tom = [[AddressCard alloc] initWithFirst: first&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&last: last&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&email: email];&&&&&&&&&&&&&&// we're done with the strings, so we must dealloc them&&&&&&&&&[first release];&&&&&&&&&[last release];&&&&&&&&&[email release];&&&&&&&&&&&&&&// print to show the retain count&&&&&&&&&printf( &Retain count: %i\n&, [[tom first] retainCount] );&&&&&&&&&[tom print];&&&&&&&&&printf( &\n& );&&&&&&&&&&&&&&&&&&// free memory&&&&&&&&&[tom release];&&&&&&&&&&&&&&return 0;
级别: 新手上路
可可豆: 221 CB
威望: 221 点
在线时间: 125(时)
发自: Web Page
这个问题有位仁兄以前讲过的,retain只是在给分配的空间上加了一把锁,不至于当用到时被别人释放!
Belive myself!
级别: 骑士
可可豆: 1950 CB
威望: 1950 点
在线时间: 118(时)
发自: Web Page
retain如果是只加锁这么简单,为何retain要用release来释放内存?
级别: 骑士
可可豆: 1950 CB
威望: 1950 点
在线时间: 118(时)
发自: Web Page
&&[first release];//&&&& 而赋值的第一次,first为NULL也能release?&&当然在第二次调用&& setFirst时,first不为空可以被释放,这点我看不懂
级别: 版主
发帖: 1755
可可豆: 112194 CB
威望: 112841 点
在线时间: 8533(时)
发自: Web Page
給您推薦兩篇文章!
一,&&&二,&&&引用 引用第3楼ltaotao007于 03:32 PM发表的&&:&  [first release];//     而赋值的第一次,first为NULL也能release?  当然在第二次调用   setFirst时,first不为空可以被释放,这点我看不懂
 Developer------------------------------------------------------------Η αγάπη ποτέ δεν αποτυγχάνει.愛是永不止息。Love never fails.
    --《圣经.新约》哥林多前书第13章
级别: 侠客
可可豆: 1059 CB
威望: 1059 点
在线时间: 245(时)
发自: Web Page
对于空值也是可以release的,这个在cocoa中允许的.&&我也给你推荐一个链接吧,不过是英文的&
简单做人,好好做事
级别: 新手上路
可可豆: 768 CB
威望: 768 点
在线时间: 294(时)
发自: Web Page
假设一个数值 为0的时候释放 也就是alloc retain 给数值加 1 release -1 就是对标志位操作而已。
级别: 新手上路
可可豆: 28 CB
威望: 28 点
在线时间: 18(时)
发自: Web Page
建议还是多看看lvyile给的或者其他的Object-C参考资料吧,NSObject基类对实例的内存管理就是用的普通的引用计数原理。
级别: 新手上路
可可豆: 620 CB
威望: 620 点
在线时间: 120(时)
发自: Web Page
retain +1, release -1. 当count 为0时才释放掉~~~~~~~~~,release不一定就释放哦,只是让count减1,
级别: 骑士
可可豆: 1128 CB
威望: 1128 点
在线时间: 70(时)
发自: Web Page
只给你两句话&1&&&& retain是对原来创建的指针援引数加一,表示又多了一个引用,防止别的引用撤去的时候指针被释放。alloc是新开辟了一块空间,创建的时候就相当于同时又执行了一次retain操作,援引数是1。&2&&&&我们在实际的应用中只有用了alloc和copy操作的时候才需要考虑在我们不用这个指针的时候要执行一次release操作,其他的情况我们可以不管,系统会自动管理内存的
不骄不躁,锐意进取!
Pages: 1/2
关注本帖(如果有新回复会站内信通知您)
苹果公司现任CEO是谁?2字 正确答案:库克
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版//& Student.h
//&&内存管理1-retain和release的简单使用
#import&&Foundation/Foundation.h&
@interface&Student :&NSObject
@property&int&
==============
//& Student.m
//&&内存管理1-retain和release的简单使用
#import&&Student.h&
@implementation&Student
@synthesize&age =&_age;&//&在xcode4.5环境下可以省略
- (void)dealloc {
& &&NSLog(@&%@被销毁了&,&self);
&& [super&dealloc];
& &&//&一定要调用super的dealloc方法,而且最好放在最后面调用
=================
//& main.m
//&&内存管理1-retain和release的简单使用
#import&&Foundation/Foundation.h&
#import&&Student.h&
void&test() {
& &&Student&*stu = [[Student&alloc]&init];&//
& &&// z代表无符号
& &&NSLog(@&count:%zi&, [stu&retainCount]);
& & [stu&retain];&// 2
& &&NSLog(@&count:%zi&, [stu&retainCount]);
& & [stu&release];&// 1
& &&NSLog(@&count:%zi&, [stu&retainCount]);
& & [stu&release];&// 0
& &&// [stu release]; //&会发生野指针错误,也就是说访问了不属于你的内存
void&test1() {
& &&// Student对象的计数器永远为1,所以不可能被释放
& & [[Student&alloc]&init].age&=&10;
& & [Student&new].age&=&10;
& &&//&上面的代码都有内存泄露
int&main(int&argc,&const&char&* argv[])
& &&@autoreleasepool&{
& &&return&0;
本文已收录于以下专栏:
相关文章推荐
retain和release倒底怎么玩?
呼呼,好久没有发布教程了(小若:难得清静了,你为毛又出来吓人= =),其实最近木头我在准备出版书籍的事情。但是貌似不太顺利,果然我还是积累不够,写书的...
内存管理1-retain和release的简单使用
@interface Student : NSObject
程序员升职加薪指南!还缺一个“证”!
CSDN出品,立即查看!
转自于http://blog.csdn.net/chaoyuan899
任何继承了NSObject
的对象,对基本数据类型无效
Objective-C在管理内存时,遵循一套简单的规则。
每一个对象都有一个名为"retainCount"的变量,它表示该对象有多少个引用。
[java] view
#synthesize关键字: 根据@property设置,自动生成成员变量相应的存取方法,从而可以使用点操作符来方便的存取该成员变量 。
@implementation 关键字,表明类的实现 ...
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 netty retain release 的文章

 

随机推荐