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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 会飞得猪 中级黑马   /  2016-2-19 23:00  /  899 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

(1)在iOS程序运行过程中,会创建无数个池子,这些池子都是以栈结构(先进后出)存在的。
(2)当一个对象调用autorelease时,会将这个对象放到位于栈顶的释放池中

autorelease
是一种支持引用计数的内存管理方式
它可以暂时的保存某个对象(object),然后在内存池自己的排干(drain)的时候对其中的每个对象发送release消息

注意,这里只是发送一次release消息,如果当时的引用计数(reference-counted)依然不为0,则该对象依然不会被释放。可以用该方法来保存某个对象,也要注意保存之后要释放该对象。

OC的内存管理机制中比较重要的一条规律是:谁申请,谁释放。

方法内部是不会写release来释放对象的,因为这样做会将对象立即释放而返回一个空对象;调用者也不会主动释放该对象的,因为调用者遵循“谁申请,谁释放”的原则。那么这个时候,就发生了内存泄露。
这就是不使用autorelease存在的问题

针对这种情况,Objective-C的设计了autorelease,既能确保对象能正确释放,又能返回有效的对象

使用autorelease的好处
(1)不需要再关心对象释放的时间
(2)不需要再关心什么时候调用release


基本用法
(1)会将对象放到一个自动释放池中
(2)当自动释放池被销毁时,会对池子里的所有对象做一次release
(3)会返回对象本身
(4)调用完autorelease方法后,对象的计数器不受影响(销毁时影响)


//autorelease原理?
autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的Autorelease pool中,当该pool被释放时,该pool中的所有Object会被调用 Release。

//autorelease何时释放?
对于autorelease pool本身,会在如下两个条件发生时候被释放
1)手动释放Autorelease pool
2)Runloop结束后自动释放
对于autorelease pool内部的对象
在引用计数的retain == 0的时候释放。release和autorelease pool 的 drain都会触发retain-- 事件。

//------------------autorelease使用注意
1)并不是放到自动释放池代码中,都会自动加入到自动释放池,如果没有调用autorelease方法,对象没有假如到自动释放池
2)在自动释放池的外部发送autorelease 不会被加入到自动释放池中

3)不管这个对象是在自动释放池内还是外创建的,只要在自动释放池内写一个
[p1 autorelease];p1就会被放到自动释放池中。
注意autorelease是一个方法,且只有在自动释放池中使用才有效。

4)自动释放池的嵌套使用
自动释放池,是在栈区创建。以压栈的方式。

5)自动释放池中不适宜放占用内存比较大的对象
1.尽量避免对大内存使用该方法,对于这种延迟释放机制,还是尽量少用
2.不要把大量循环操作放到同一个 @autoreleasepool 之间,这样会造成内存峰值的上升

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马