@autorelease{} 的详细介绍

前言:当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,因此自动释放池 定义的作用域内的其它对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。

1.  ojc-c 是通过一种"referring counting"(引用计数)的方式来管理内存的,  对象在开始分配内存(alloc)的时候引用计数为一,以后每当碰到有alloc,new,copy,retain的时候引用计数都会加一,  每当碰到release和autorelease的时候引用计数就会减一,如果此对象的计数变为了0, 就会被系统销毁.

2. NSAutoreleasePool 就是用来做引用计数的管理工作的,这个部分后面会详细说到.

3. autorelease和release没什么区别,只是引用计数减一的时机不同而已,autorelease会在对象的使用真正结束的时候才做引用计数减一.

4.设定项目编译环境为ARC下时,编译器会帮助我们在程序的入口main函数就调用NSAutoreleasePool


,这样保证程序中不调用NSAutoreleasePool,但在退出时自动释放

1.NSAutoreleasePool是什么?

NSAutoreleasePool实际上是个对象引用计数自动处理器,在官方文档中被称为是一个类。

NSAutoreleasePool可以同时有多个,它的组织是个栈,总是存在一 个栈顶pool,也就是当前pool,每创建一个pool,就往栈里压一个,改变当前pool为新建的pool,然后,每次给pool发送drain消 息,就弹出栈顶的pool,改当前pool为栈里的下一个 pool。

2.NSAutoreleasePool可以用来做什么,怎么用?

NSAutoreleasePool可以在一定程度上帮助我们苹果开发程序员管理内存,让我们的工作更加严密,简便。

1)在ARC项目中,系统会自动帮助我们在程序中嵌入NSAutoreleasePool,此为苹果公司程序员在写这个编译器的时候设定的;

2)在MRC项目中,我们需要自己去创建NSAutoreleasePool类对象去帮助我们管理内存;

3)使用应注意:

a.在ARC项目中我们同样可以创建NSAutoreleasePool类对象去帮助我们更精确的管理内存问题。

b. NSAutoreleasePool的管理范围是在NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];与[pool release];之间的对象

c..既然ARC项目中设置了ARC,为什么还要使用@autoreleasepool?(注意a的案例解释)

ARC 并不是舍弃了@autoreleasepool,而是在编译阶段帮你插入必要的retain/release/autorelease的代码调用。

所以,跟你想象的不一样,ARC 之下依然是延时释放的,依然是依赖于NSAutoreleasePool,跟非 ARC 模式下手动调用那些函数本质上毫无差别,只是编译          器来做会保证引用计数的正确性。

参考:Retain count semantics in ARC

What's @autoreleasepool

d.NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];

当执行[pool autorelease]的时候,系统会进行一次内存释放,把autorelease的对象释放掉,如果没有NSAutoreleasePool , 那这些内存不会释放

注意,对象并不是自动被加入到当前pool中,而是需要对对象发送autorelease消息,这样,对象就被加到当前pool的管理里了。当当前pool接受到drain消息时,它就简单的对它所管理的所有对象发送release消息。(如例子1)

e.在ARC项目中.不能直接使用autorelease pools,而是使用@autoreleasepool{},

@autoreleasepool{}比直接使用NSAutoreleasePool效率高。不使用ARC的时候也可以使用(autorelease嵌套)

4)使用例子:

例子1:

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSString* nsstring;

char* cstring = "Hello CString";

nsstring = [NSString stringWithUTF8String:cstring];

[pool release];(这一行代码就是在给pool发送drain消息了)

官方API摘抄翻译:

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方法测试你的应用是否是多线程模式

PS:

我把它理解为:新开线程最好实现NSAutoreleasePool(当 我们点击一个App中的一个按钮或者其他可以触碰开启新业务的UI控件,在程序里面就会自动开启一条新线程,当我们不用这个业务的时候,就需要程序帮我们 提前在“程序的主窗口的所有代码编译结束后”之前关闭这条线程以优化线程的使用,一定程度上尽量避免线程开启太多占用CPU严重引起的卡顿问题)(业务逻 辑处理-业务线程优化)

详细可以参考官方API的NSAutoreleasePool Class Reference

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 前言:当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。...
    mengyingguo阅读 1,130评论 0 0
  • 37.cocoa内存管理规则 1)当你使用new,alloc或copy方法创建一个对象时,该对象的保留计数器值为1...
    如风家的秘密阅读 827评论 0 4
  • 前言 从我开始学习iOS的时候,身边的朋友、网上的博客都告诉我iOS的内存管理是依靠引用计数的,然后说引用计数大于...
    盖世英雄_ix4n04阅读 542评论 0 1
  • 内存管理 简述OC中内存管理机制。与retain配对使用的方法是dealloc还是release,为什么?需要与a...
    丶逐渐阅读 1,946评论 1 16
  • 这学期意外的很喜欢上课的日子 许是能趁着这时候可以明目张胆的做些悠闲的事情 所谓悠闲 也无外乎刷手机和胡思乱想了 ...
    好一朵迎春fa阅读 297评论 0 0