A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© heqiuge369 初级黑马   /  2015-4-14 00:04  /  3684 人查看  /  19 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

10黑马币
谁能解释下Autorelease 和 release 的区别?

最佳答案

查看完整内容

自动释放池: NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init ]; ; 事实上程序中可以有多个自动释放池。自动释放池其实并不包含实际的对象本身,仅仅是对释放的对 象的引用。通过向目前的自动释放池发送一条autorelease 消息,可以将一个对象添加到其中。 release 其实就是个引用计数器,不再需要对象时,可以通过发送 release 消息,使对象的引用次数减 1。 ...

19 个回复

倒序浏览
自动释放池:
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init ]; [pool drain];
事实上程序中可以有多个自动释放池。自动释放池其实并不包含实际的对象本身,仅仅是对释放的对 象的引用。通过向目前的自动释放池发送一条autorelease 消息,可以将一个对象添加到其中。

release 其实就是个引用计数器,不再需要对象时,可以通过发送 release 消息,使对象的引用次数减 1。
回复 使用道具 举报
很好谢谢!
回复 使用道具 举报
release 方法会立刻减少对象的引用计数,因此如果对象的引用计数为1,会导致立刻被销毁。
autoRelease()方法会在渲染下一帧时减少对象的引用计数, autoRelease 也会自动处理线程相关问题,因此使用autoRelease 可以保证在当前调用栈中对象不会被立刻销毁。
希望对你有用。
回复 使用道具 举报
本帖最后由 发飙的蜗牛 于 2015-4-14 01:05 编辑

1.
如果能够真正的理解autorelease,那么才是理解了Objective c的内存管理。Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的Autorelease pool中,当该pool被释放时,该pool中的所有Object会被调用Release。实际上对于[NSString stringWithFormat:1.0] 这类构造函数返回的对象都是autorelease的。

2.
autorelease pool来避免频繁申请/释放内存(就是pool的作用了)。这个应该是相对比较好理解的。
总结:(1)一定要注意Autorelease pool的生存周期,理解Runloop,避免在对象被释放后使用。
(2)[NSString stringWithFormat]这类函数返回的对象是不需要再自己release的,它已经被autorelease了, 如果你想把它当一个全局对象使用,那必须自己再retain,释放时再release。为什么需要Auto release ?这个auto release有什么好,象C/C++那样,自己申请,自己释放,完全可控不好么,这个auto relase 完全不可控,你都不知到它什么时候会被真正的release。
我的理解它有一个作用就是可以做到每个函数对自己申请的对象负责,自己申请,自己释放,该函数的调用者不需要关心它内部申请对象的管理。
在下面这个例子中,Func1的调用者不需要再去关心obj的释放。ClassA *Func1() { ClassA *obj = [[[ClassA alloc]init]autorelease]; return obj; } (1)Iphone项目中,大家会看到一个默认的Autorelease pool,程序开始时创建,程序退出时销毁,按照对Autorelease的理解,岂不是所有autorelease pool
里的对象在程序退出时才release,这样跟内存泄露有什么区别?答案是,对于每一个Runloop,系统会隐式创建一个Autorelease pool,这样所有的release pool会构成一个象CallStack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的Autorelease pool会被销毁,这样这个pool里的每个Object会被release。那什么是一个Runloop呢?一个UI事件,Timer call,delegate call,都会是一个新的Runloop。例子如下:
NSString* globalObject;
- (void)applicationDidFinishLaunching:(UIApplication *)application

回复 使用道具 举报
autorelease更加tricky,而且很容易被它的名字迷惑。我在这里要强调一下:autorelease不是garbage collection,完全不同于Java或者.Net中的GC。

autorelease和作用域没有任何关系!
autorelease原理:
1.先建立一个autorelease pool
2.对象从这个autorelease pool里面生成。
3.对象生成之后调用autorelease函数,这个函数的作用仅仅是在autorelease pool中做个标记,让pool记得将来release一下这个对象。
4.当pool要把池中的对象release的时候,pool本身也需要rerlease, 此时pool会把每一个标记为autorelease的对象release一次。如果某个对象此时retain count大于1,这个对象还是没有被销毁。(被标为autorelease的对象,并不是等程序结束时才release,如:在viewDidLoad中创建一个autorelease对象,在viewDidLoad走完,一次消息循环完毕,这个autorelease pool中的对象就会被release,button的点击事件,点击代码执行完会release一下autolease类型的变量)

上面这个例子应该这样写:
ClassName *myName = 【[[ClassName alloc] init] autorelease];//标记为autorelease
[classA setName:myName]; //retain count == 2  (如果myName的属性是retain的话)
[myName release]; //retain count==1,注意,在ClassA的dealloc中不能release name,否则release pool时会release这个retain count为0的对象,这是不对的。

记住一点:如果这个对象是你alloc或者new出来的,你就需要调用release。如果使用autorelease,那么仅在发生过retain的时候release一次(让retain count始终为1)。
回复 使用道具 举报
shicuf 中级黑马 2015-4-14 22:23:30
7#
一句话概括,自动释放和手动释放的区别!autorelease由系统负责何时对其进行一次release操作,而手动调用release会立即让引用计数-1
回复 使用道具 举报
不好意思 我不知道怎么解释, 但我找到了网站http://blog.itpub.net/14466241/viewspace-744587/
回复 使用道具 举报
一定要注意Autorelease pool的生存周期,理解Runloop,避免在对象被释放后使用
回复 使用道具 举报
release消息发送后要会引起对象的retainCount减1
autorelease消息发送后是将对象装进自动释放池中,当自释放池结束时,自动释放再对池中所有对象进retainCount减1操作的。
回复 使用道具 举报
uibe 中级黑马 2015-4-15 20:10:45
11#
1.如果能够真正的理解autorelease,那么才是理解了Objective c的内存管理。Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的Autorelease pool中,当该pool被释放时,该pool中的所有Object会被调用Release。 实际上对于 [NSString stringWithFormat:1.0] 这类构造函数返回的对象都是autorelease的。  
2. autorelease pool来避免频繁申请/释放内存(就是pool的作用了)。这个应该是相对比较好理解的。  
总结:(1)一定要注意Autorelease pool的生存周期,理解Runloop,避免在对象被释放后使用。  
          (2)[NSString stringWithFormat]这类函数返回的对象是不需要再自己release的,它已经被autorelease了, 如果你想把它当一个全局对象使用,那必须自己再retain, 释放时再release。  
  
回复 使用道具 举报
Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的Autorelease pool中,当该pool被释放时,该pool中的所有Object会被调用Release。象C/C++那样,自己申请,自己释放,完全可控不好么, 这个auto relase 完全不可控,你都不知到它什么时候会被真正的release。我的理解它有一个作用就是可以做到每个函数对自己申请的对象负责,自己申请,自己释放,该函数的调用者不需要关心它内部申请对象的管理。
回复 使用道具 举报
autorelease和release都是内存释放的方法,都实现计数器减一的操作。
使用场合是不一样的。
autorelease是配合自动释放池使用,也就是半自动释放内存,只要你在自动释放池中,创建对象的时候调用autorelease方法,在自动释放池结束时,系统会帮你释放这个对象的内存,实现引用计数器减一的操作。

release完全就是手动管理内存,你什么时候想回收对象内存,或者想实现对象引用计数器减一的操作,再手动调用这个方法
回复 使用道具 举报
都是计数器减一操作,只是减一时机不一样

autorelease是relese的使用延迟  放池结束时 系统会帮你释放这个对象的内存

release就是马上对计数器减一
回复 使用道具 举报
Autorelease 会由系统自动释放  而release是你手动释放
回复 使用道具 举报
autorelese和relese只是引用计数减一的时机不同,autorelese会在对象的使用真正结束的时候才做引用计算减一
回复 使用道具 举报
如果这个对象是你alloc或者new出来的,你就需要调用release。如果使用autorelease,那么仅在发生过retain的时候release一次
回复 使用道具 举报
Autorelease是延迟了对象的销毁,对象的计数器不变,用这个关键字创建的对象系统会自动放进自动释放池,当自动释放池销毁的时候,里面的使用Autorelease 的对象全部被销毁,不需要再调用release ,当对象调用release方法的时候,其计数器-1,当计数器变为0的时候对象就会被销毁。
回复 使用道具 举报
autorelease与release相似,是OC中的一个对象方法。这两个方法都能把对象的引用计数器减1,但是release是一个精确的减1,对对象的操作只能在release之前进行,如果是在之后,就会出现野指针错误;而autorelease是一个不精确的引用计数器减1,当给对象发送autorelease消息时,对象就会被放到自动释放池中,自动销毁时会给池中的所有对象发送release消息,使得所有对象的计数器减1,所以本质上autorelease还是会调用release
回复 使用道具 举报
Itboy 来自手机 初级黑马 2015-6-5 09:36:01
20#
autoreleasepool是自动释放你申请的所有内存,而alloc是你手动对内存释放一次,听好,是一次,有多少内存块就释放多少次,所以就很繁琐,
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马