autorelease(转)
总觉得autorelease这里掌握的不到位,但涉及到内存管理,实在不可小视。今天参考了网上的不少文章和官方API文档,做了如下总结。
1、autorelease是什么?
autorelease是一种支持引用计数的内存管理方式
它可以暂时的保存某个对象(object),然后在内存池自己的排干(drain)的时候对其中的每个对象发送release消息
注意,这里只是发送release消息,如果当时的引用计数(reference-counted)依然不为0,则该对象依然不会被释放。可以用该方法来保存某个对象,也要注意保存之后要释放该对象。
autorelease可以通过NSAutoreleasePool创建实例
2、为什么会有autorelease?
OC的内存管理机制中比较重要的一条规律是:谁申请,谁释放
考虑这种情况,如果一个方法需要返回一个新建的对象,该对象何时释放?
方法内部是不会写release来释放对象的,因为这样做会将对象立即释放而返回一个空对象;调用者也不会主动释放该对象的,因为调用者遵循“谁申请,谁释放”的原则。那么这个时候,就发生了内存泄露。
针对这种情况,Objective-C的设计了autorelease,既能确保对象能正确释放,又能返回有效的对象。
在autorelease的模式下,下述方法是合理的,即可以正确返回结果,也不会造成内存泄露
ClassA *Func1()
{
ClassA *obj = [[[ClassA alloc]init]autorelease];
return obj;
}
3、autorelease是什么原理?
Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当 前的Autorelease pool中,当该pool被释放时,该pool中的所有Object会被调用Release。
4、autorelease何时释放?
对于autorelease pool本身,会在如下两个条件发生时候被释放(详细信息请参见第5条)
1)、手动释放Autorelease pool
2)、Runloop结束后自动释放
对于autorelease pool内部的对象
在引用计数的retain == 0的时候释放。release和autorelease pool 的 drain都会触发retain--事件。
5、autorelease释放的具体原理是什么?
要搞懂具体原理,则要先要搞清楚autorelease何时会创建。
我们的程序在main()调用的时候会自动调用一个autorelease,然后在每一个Runloop, 系统会隐式创建一个Autorelease pool,这样所有的release pool会构成一个象CallStack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的 Autorelease pool(main()里的autorelease)会被销毁,这样这个pool里的每个Object会被release。
可以把autorelease pool理解成一个类似父类与子类的关系,main()创建了父类,每个Runloop自动生成的或者开发者自定义的autorelease pool都会成为该父类的子类。当父类被释放的时候,没有被释放的子类也会被释放,这样所有子类中的对象也会收到release消息。
那什么是一个Runloop呢? 一个UI事件,Timer call, delegate call, 一个鼠标事件,键盘按下(MAC OSX),或者iphone上的触摸事件,异步http连接下后当接收完数据时,都会是一个新的Runloop。
一般来说,消息循环运行一次是毫秒级甚至微秒级的,因此autorelease的效率仍然是非常高的,确实是一个巧妙的设计。
6、使用有什么要注意的?
1)、NSAutoreleasePool可以创建一个autorelease pool,但该对象本身也需要被释放,如:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init;
// Code benefitting from a local autorelease pool.
[pool release];
在引用计数环境下,使用[pool release]或[pool drain]效果是相同的,drain仅适用于max os高版本,低版本不适用,而release通用,其它并无太大差别。
2)、在ARC下,不能使用上述方式调用autorelease,而应当使用@autoreleasepool,如:
@autoreleasepool {
// Code benefitting from a local autorelease pool.
}
3)、尽量避免对大内存使用该方法,如图片。对于这种延迟释放机制,还是尽量少用,最好只用在方法内返回小块内存申请地址值的情况下,且
参考和领会OC的一些系统方法,如:[NSString stringWithFormat:]
4)、不要把大量循环操作放到同一个NSAutoreleasePool之间,这样会造成内存峰值的上升。
7、关于多线程,有什么要注意的?
我还未实际使用到,在官方API翻译出类似如下语句:
1)、对于不同线程,应当创建自己的autorelease pool。如果应用长期存在,应该定期drain和创建新的autorelease pool
下面这句话摘自官方API,大概是说多线程中如果没有使用到cocoa的相关调用,则不需要创建autorelease pool,我一直没有理解透彻
If, however, your detached thread does not make Cocoa calls, you do not need to create an autorelease pool.
2)、如果不是使用的NSThread,就不要用aoturelease pool,除非你是多线程模式(multithreading mode) ,可以使用NSThread的isMultiThreaded方法测试你的应用是否是多线程模式
详细可以参考官方API的NSAutoreleasePool Class Reference
3
喜欢
0
赠金笔
autorelease(转)的更多相关文章
- Autorelease返回值的快速释放机制
+ (instancetype)createSark { return [self new];}// callerSark *sark = [Sark createSark]; 编译器改写成了形如下面 ...
- 用类方法------>快速创建一个autorelease的对象,在封装的类方法内部
在封装的类方法内部,也就是+ (id)personWithName:(NSString *)name andAge:(int)age内部: 创建了一个person对象,并且创建了一个person*类型 ...
- 理解autorelease
如果你能够真正的理解autorelease,那么你才是理解了Objective c的内存管理.Autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是 ...
- RunLoop和autorelease的一道面试题
有这么一道iOS面试题 以下代码有没有什么问题?如果有?如何解决? for (int i = 0; i < largeNumber; i++) { NSString *str = [NSStri ...
- Autorelease自动释放池的使用
Autorelease自动释放池的使用 使用ARC开发,只是在编译时,编译器会根据代码结构自动添加了retain.release和autorelease. MRC内存管理原则:谁申请,谁释放 遇到al ...
- 2016 - 2 - 20 ARC知识总结(二 autorelease概念及实现)
首先祝自己生日快乐~23咯~ 一 autorelease的概念 autorelease会像C语言的自动变量那样来对待对象实例.当超出作用域(相当于变量作用域)时,对象的实例release实力方法被调 ...
- 【引】objective-c,6:Autorelease Pool
参考博客: http://blog.leichunfeng.com/blog/2015/05/31/objective-c-autorelease-pool-implementation-princi ...
- 黑马程序员-autorelease pool
Autorelease:可以延迟给对象发送release消息.发送一个autorelease消息给对象,证明该对象在一定时间内有效,一定时间后会对该对象进行释放,进行一次release. 一个auto ...
- 【原】你真的懂iOS的autorelease吗?
或许这个题目起得有点太高调了,不过我只是想纠正一些童鞋对于autorelease的认识,如果能帮到几个人,那这篇文章也就值得了!当然,高手请绕道 本文主要探讨两个方面:(1)autorelease对象 ...
- retain,copy,assign及autorelease ,strong,weak
一,retain, copy, assign区别 1. 假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了b.此时a ...
随机推荐
- 调整altium designer15的十字光标大小
在左上角的DXP下preferences中调整.首先打开该窗口. 1.原理图:schematic-----graphical editing,此窗口中cursor栏有个cursor type,其下拉菜 ...
- 3个QT新闻网,2个发烧友网站
http://planet.qt.io/ http://blog.basyskom.com/2015/introducing-qtopcua/ http://www.qtworldsummit.com ...
- bzoj2821作诗
http://www.lydsy.com/JudgeOnline/problem.php?id=2821 分块 我们把数列分成$\sqrt{N}$块 记$f[i][j]$表示第i块到第j块的答案,这个 ...
- cf500D New Year Santa Network
D. New Year Santa Network time limit per test 2 seconds memory limit per test 256 megabytes input st ...
- HDU_2022——海选女主角
Problem Description potato老师虽然很喜欢教书,但是迫于生活压力,不得不想办法在业余时间挣点外快以养家糊口.“做什么比较挣钱呢?筛沙子没力气,看大门又不够帅...”potato ...
- hdu3534,个人认为很经典的树形dp
题目大意为,求一个树的直径(最长路),以及直径的数量 朴素的dp只能找出某点开始的最长路径,但这个最长路径却不一定是树的直径,本弱先开始就想简单了,一直wa 直到我看了某位大牛的题解... 按照那位大 ...
- [LeetCode] 116. Populating Next Right Pointers in Each Node 解决思路
Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *nex ...
- NOI2014 D2T3 购票 简单粗暴解法(凸包维护)
之前说过这题能用点分治(详见 http://www.cnblogs.com/jasonyu/p/noi2014.html),但其实还有更粗暴的解法. 要求出一个点的答案,我们需要知道树上一段路径的点形 ...
- AngularJS和ReactJS对比
Angular的特点: 优势: AngularJS是一套完整的框架,angular有自带的数据绑定.render渲染.angularUI库,过滤器,$filter,$directive(模板),$se ...
- Android较低版本(<5.2) 页面默认Select选择框效果的BUG解决
Bug描述: 使用低版本安卓(<5.2),在微信上打开网页,点击下拉框,会出现如下图所示的用来展示select选项的弹出框: 在选项较少的时候,可以向下滑动,将选项滑到底部 滑动前: 滑动后: ...