iOS ARC学习汇总

ARC

ARC是什么

ARC是iOS 5推出的新功能,全称叫 ARC(Automatic Reference Counting)。简单地说,就是编译阶段自动做了retain/release,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。就ARC并不是GC,不是运行时内存管理,不会做malloc/free的工作,它只是一种代码静态分析(Static Analyzer)工具。
比如,我们生成一个对象:

addretain.png

编译器会给我们添加上retain/release/autorelease


add2.png

比如,block的写法,编译器背后给我们做的事:

add3.png

ARC之前的手工管理内存

我们需要手动retain和 release对象。如下:

 // First you create an object, which you then own ("retain")
 // Retain count = 1
 Customer *newCustomer = [[Customer alloc] init];

 // Next, you do something with the new object, such as add it to an 
 // array, which also now retains it. Retain count = 2

 [customerArray addObject:newCustomer];

 // When finished with the object, you relinquish (release) ownership. 
 // Retain count = 1

 [newCustomer release];

 // At some point customerArray is also released, releasing all of the
 // objects it contains. Retain count = 0, and the original object is 
 // finally deallocated

 [customerArray release];

这个过程很容易出错。所以苹果引入ARC,在编译阶段自动帮我们做retain/release的工作,如下图,减少了很多代码。


add4.png

手工引用计数规则

  • 用“alloc”, “new”, “copy”, or “mutableCopy”等方法生成object的时候,object 的引用计数为1.
    When you create an object, it has a retain count of 1. You create an object using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or mutableCopy).
  • 向object发送retain消息,它的引用计数+1.
    When you send an object a retain message, its retain count is incremented by 1.
  • 向object发送release消息,引用计数-1.
    When you send an object a release message, its retain count is decremented by 1.

  • 向object发送autorelease消息,引用计数-1.当引用计数为0,object被释放 。
    When you send an object a autorelease message, its retain count is decremented by 1 at the end of the current autorelease pool block.If an object’s retain count is reduced to zero, it is deallocated.

trace_obj.png

ARC:自动引用计数

ARC模式下,引用计数的规则还起作用,只是编译器做retain,release,autorelease的工作。

内存管理和引用计数

WWDC Adopting Automatic Reference Counting

翻译

ARC基本规则

参考:

Transitioning to ARC Release Notes

规则总结

规则:

  • You cannot explicitly invoke dealloc, or implement or invoke retain, release, retainCount, or autorelease.

  • You cannot use NSAllocateObject or NSDeallocateObject.

  • You cannot use object pointers in C structures.

  • There is no casual casting between id and void *.

  • You cannot use NSAutoreleasePool objects.

  • You cannot use memory zones.

  • You cannot give an accessor a name that begins with new. This in turn means that you can’t, for example,

    // Won't work:
    @property NSString *newTitle;
    
    // Works:
    @property (getter=theNewTitle) NSString *newTitle;`                                   
    

Is ARC slow?

It depends on what you’re measuring, but generally “no.” The compiler efficiently eliminates many extraneous retain/release calls and much effort has been invested in speeding up the Objective-C runtime in general. In particular, the common “return a retain/autoreleased object” pattern is much faster and does not actually put the object into the autorelease pool, when the caller of the method is ARC code.

引用类型:

ARC强引用和弱引用

Strong reference : 强引用指针增加对象引用计数。

Weak reference :弱引用指针不增加对象引用计数,对象被释放后,指针被置为nil

引用关键字:

__strong:_strong修饰符表示对对象的“强引用”。持有强引用的变量在超出其作用域时被废弃,随着强引用的失效,引用的对象会随之释放

__weak:

使用_strong修饰符的成员变量在持有对象时,很容易发生循环引用。

循环引用容易发生内存泄露。内存泄露就是应当废弃的对象在超出其生存周期后继续存在。

使用_weak修饰符可以避免循环引用。_weak修饰符还有另一有优点。在持有某对象的弱引用时,若该对象被废弃,则此弱引用将自动失效且处于nil被赋值的状态(空弱引用)。

__unsafe_unretained__

autoreleasing

使用关键字的格式,关键字在*号之后

MyClass * __weak myWeakReference;
MyClass * __unsafe_unretained myUnsafeReference;                                            

循环引用

三种循环引用的模式:
  • 对象之间有“父子关系
  • Delegate模式
  • Blocks
解决方法:

ARC循环引用

管理Autorelease Pools

@autoreleasepool-内存的分配与释放

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-CJBFBEDI

使用autorelease pool 的场景:

  • 程序不基于 UI framework.
    If you are writing a program that is not based on a UI framework, such as a command-line tool.

  • 在循环中生成大量的临时变量,可以在for循环中用autorelease pool block。
    If you write a loop that creates many temporary objects.
    You may use an autorelease pool block inside the loop to dispose of those objects before the next iteration. Using an autorelease pool block in the loop helps to reduce the maximum memory footprint of the application.

  • Cocoa application中的每个线程维护自己的 autorelease pool block堆栈,所以开子线程需要生成自己的autorelease pool block.

    You must create your own autorelease pool block as soon as the thread begins executing; otherwise, your application will leak objects. (See Autorelease Pool Blocks and Threads for details.)

对象转换

在iOS世界,主要有两种对象:Objective-C 对象和 Core Foundation 对象0。Core Foundation 对象主要是有C语言实现的 Core Foundation Framework 的对象,其中也有对象引用计数的概念,只是不是 Cocoa Framework::Foundation Framework 的 retain/release,而是自身的 CFRetain/CFRelease 接口。

这两种对象间可以互相转换和操作,不使用ARC的时候,单纯的用C原因的类型转换,不需要消耗CPU的资源,所以叫做 Toll-Free bridged

对象转换

Transitioning to ARC Release Notes

  • __bridge` transfers a pointer between Objective-C and Core Foundation with no transfer of ownership.

  • __bridge_retained or CFBridgingRetain casts an Objective-C pointer to a Core Foundation pointer and also transfers ownership to you.

    You are responsible for calling CFRelease or a related function to relinquish ownership of the object.

  • __bridge_transfer or CFBridgingRelease moves a non-Objective-C pointer to Objective-C and also transfers ownership to ARC.

    ARC is responsible for relinquishing ownership of the object.


易飞扬,ARC系列

理解ARC强引用和弱引用指针类型

BeginARC

WWDC Adopting Automatic Reference Counting

内存管理和引用计数

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

推荐阅读更多精彩内容

  • 内存管理 简述OC中内存管理机制。与retain配对使用的方法是dealloc还是release,为什么?需要与a...
    丶逐渐阅读 1,867评论 1 16
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,036评论 29 470
  • 37.cocoa内存管理规则 1)当你使用new,alloc或copy方法创建一个对象时,该对象的保留计数器值为1...
    如风家的秘密阅读 768评论 0 4
  • 1.OC里用到集合类是什么? 基本类型为:NSArray,NSSet以及NSDictionary 可变类型为:NS...
    轻皱眉头浅忧思阅读 1,295评论 0 3
  • 感恩自己定下早起的目标,感受到清新的空气 感恩身体的健康,感恩身体的每个器官,让我感受生活的美好。 感恩善心汇的平...
    银媛阅读 73评论 0 0