iOS应用开发:什么是ARC

 

ARC是什么

ARC是iOS 5推出的初效能,全称于 ARC(Automatic Reference
Counting)。简单地游说,就是代码中活动进入了retain/release,原先用手动添加的所以来拍卖内存管理的援计数的代码可以活动地由于编译器完成了。

该机能于 iOS 5/ Mac OS X 10.7 开始导入,利用 Xcode4.2
可以用该意义。简单地领略ARC,就是经点名的语法,让编译器(LLVM
3.0)在编译代码时,自动生成实例的援计数管理有代码。有好几,ARC并无是GC,它只是同样种植代码静态分析(Static
Analyzer)工具。

 

变化点

通过一致不怎么截代码,我们看用ARC前后的变化点。

 

C代码  图片 1

  1. @interface NonARCObject : NSObject {    
  2.     NSString *name;    
  3. }    
  4. -(id)initWithName:(NSString *)name;    
  5. @end    
  6.    
  7. @implementation NonARCObject    
  8. -(id)initWithName:(NSString *)newName {    
  9.     self = [super init];    
  10.     if (self) {    
  11.         name = [newName retain];    
  12.     }    
  13.     return self;    
  14. }    
  15.    
  16. -(void)dealloc {    
  17.     [name release];    
  18.     [Super dealloc];    
  19. }    
  20. @end    

 

 

C代码  图片 2

  1. @interface ARCObject : NSObject {    
  2.     NSString *name;    
  3. }    
  4. -(id)initWithName:(NSString *)name;    
  5. @end    
  6.    
  7. @implementation ARCObject    
  8. -(id)initWithName:(NSString *)newName {    
  9.     self = [super init];    
  10.     if (self) {    
  11.         name = newName;    
  12.     }    
  13.     return self;    
  14. }    
  15. @end    

 

 

咱们事先运用Objective-C中内存管理规则时,往往利用下面的守则

  •    生成对象时,使用autorelease
  •    对象代入常,先autorelease后再retain
  •    对象在函数中归时,使用return [[object retain] autorelease];

假使用ARC后,我们可以无需这么做了,甚至连最基础的release都无待了。

 

说明:在arc中,strong对应原来的retain与copy,weak对应原来的assign。

 

arc的使用有两点:

A:在build phases中修改compiler Flags值。

B:在代码中判断是否支持arc,包括对属性(property)、释放(release)的判断。

 

在dealloc中需要这样做:

类如果注册了通知(观察者模式),需要remove掉。这个不管是否支持arc,都必须要做的。

– (void)dealloc {

[[NSNotificationCenterdefaultCenter] removeObserver:self];//如果注册了通知的话。

[self removeObserver:self forKeyPath:keyPath];//如果注册了kvo的话。

#if !__has_feature(objc_arc)  //在这里也需要判断是否支持arc,支持的话就执行旧工程中该release的语句.

    [array release]; //array代表alloc但没有autorelease的变量

    [super dealloc];

#endif

}

 

 

总结:

 

1,arc的设置是在build phases中修改compiler Flags的值。

 

2,如果使用了arc,在你的代码中不可以使用retain, release, autorelease,如果使用的话会报错。

 

3,如果使用了arc,在@property声明中,用strong和weak代替相应的retain, copy,和assign。

 

4,如果使用了arc,NSAutoReleasePool也不能使用,测试发现,用@autoreleasepool 代替,不会编译报错。

 

 

 

总之,一切你之前“背过”的那几条内存管理规则,你都不用去管了。而且,个人感觉,用arc代码清晰很多,而且效率也提高了些。

 

 

 

 

使用ARC的好处

采用ARC有什么好处呢?

  •    看上面的事例,大家就亮了,以后写Objective-C的代码变得简单多了,因为咱们无需操心烦人的内存管理,担心内存泄露了
  •    代码的总量变少了,看上去清爽了多,也省了劳动力
  •    代码高速化,由于采用编译器管理引用计数,减少了没用代码的可能性

 

坏的地方

  •    记住一积聚新的ARC规则 — 关键字与特色等需肯定之习周期
  •  
     一些原来的代码,第三着代码应用的时刻比较费心;修改代码用工数,要么修改编译开关

有关第二碰,由于 XCode4.2 中缺省ARC就是 ON
的状态,所以编译旧代码的上屡次时有发生”Automatic Reference Counting
Issue”的错误信息。

 

图片 3

 

夫时段,可以用项目编译设置中的“Objectice-C Auto Reference
Counteting”设为NO。如下所示。

 

图片 4

 

若只有想对某个个.m文件未适于ARC,可以独自针对此类文件加上 -fno-objc-arc
编译FLAGS,如下图。

 

图片 5

 

ARC基本规则

  •     retain, release, autorelease,
    dealloc由编译器自动插入,不可知当代码中调用
  •    
    dealloc虽然足吃重载,但是非克调用[super dealloc]

鉴于ARC并无是GC,并要有的平整为编译器支持代码插入,所以必须懂得了解了这些规则后,才会写起健康的代码。

 

Objective-C对象

ObjectiveC中的目标,有胜过参照(Strong reference)和死亡参照(Weak
reference)之分,当得保障其他对象的时节,需要retain以确保目标引用计数加1。对象的持有者(owner)只要在,那么该对象的胜参照就一直存在。

目标处理的骨干规则是

  •     只要对象的所有者在(对象为高参照),那么就可采取该目标
  •     对象失去了主人后,即给破弃

 

强参照 (Strong reference)

 

图片 6

 

(s1)

firstName作为”natsu”字符串对象的初期持有者,是欠NSString类型对象的Strong
reference。

(s2)

此用firstName代入到aName中,即aName也变为了@”natsu”字符串对象的所有者,对于拖欠目标,aName也是Strong
reference。

(s3)

此处,改变firstName的始末。生成新的字符串对象”maki”。这时候firstName成为”maki”的所有者,而@”natsu”的持有者只有aName。每个字符串对象还来独家的主人,所以它们还在内存中还留存。

(s4)

增加新的变量otherName,
它以变成@”maki”对象的任何一个持有者。即NSString类型对象的Strong
reference。

(s5)

拿otherName代入到aName,这时,aName将改为@”maki”字符串对象的主人。而目标@”natsu”已经没所有者了,该目标将让破弃。

 

弱参照 (Weak reference)

接下我们来瞧弱参照 (Weak reference) 的施用办法。

 

图片 7

 

(w1)

及大参照方式同样,firstName作为字符串对象@”natsu”的所有者在。即凡拖欠NSString类型对象的Strong
reference。

(w2)

用主要字__weak,声明弱参照weakName变量,将firstName代入。这时weakName虽然参照@”natsu”,但依照是Weak
reference。即weakName虽然能顾@”natsu”,但未是其主人。

(w3)

firstName指于了初的靶子@”maki”,成为那个主人,而目标@”natsu”因为没有了主人,即吃破弃。同时weakName变量将于电动代入nil。

 

引用关键字

ARC中关于目标的援参照,主要有脚几乎拉扯键字。使用strong, weak,
autoreleasing限定的变量会让隐式初始化为nil。

 

  • __strong

变量声明缺省都蕴涵__strong关键字,如果变量什么要字还不写,那么差省就是强参照。

 

  • __weak

方已经观望了,这是故参照的显要字。该概念是新特征,从 iOS 5/ Mac OS X
10.7
开始导入。由于此类型不影响对象的生命周期,所以若目标之前即没有所有者,那么会冒出恰恰创立就让破弃的题材,比如下面的代码。

 

C代码  图片 8

  1. NSString __weak *string = [[NSString alloc] initWithFormat:@”First Name: %@”, [self firstName]];    
  2. NSLog(@”string: %@”, string); //此时 string为空   

 

只要编译设定OS版本 Deployment Target
设定也这比较就没有的本,那么编译时将报错(The current deployment target
does not support automated __weak
references),这个上,我们可以采取下的 __unsafe_unretained。

已故参照还有一个特色,即当参数对象失去所有者之后,变量会于机关付上nil
(Zeroing)。

 

  • __unsafe_unretained

该要字和__weak一样,也是去世参照,与__weak的分只是是否实施nil赋值(Zeroing)。但是如此,需要留意变量所倚的目标就让破弃了,地址还尚在,但内存中对象就没有了。如果要看该目标,将引起「BAD_ACCESS」错误。

 

  • __autoreleasing

该要字而对像延迟释放。比如你想传一个未初始化的对像引用到一个计中,在是措施被实例化此对像,那么这种状态可以使用__autoreleasing。他被常用来函数有价参数返回时之处理,比如下面的事例。

  

C代码  图片 9

  1. – (void) generateErrorInVariable:(__autoreleasing NSError **)paramError {    
  2.     ….    
  3.     *paramError = [[NSError alloc] initWithDomain:@”MyApp” code:1 userInfo:errorDictionary];    
  4. }    
  5.    
  6. ….    
  7. {    
  8.     NSError *error = nil;    
  9.     [self generateErrorInVariable:&error];    
  10.     NSLog(@”Error = %@”, error);    
  11. }    

 

再就是使函数的返回值是在函数中申请之,那么希望放走是当调用端时,往往有下面的代码。

 

C代码  图片 10

  1. -(NSString *)stringTest    
  2. {    
  3.     NSString *retStr = [NSString stringWithString:@”test”];    
  4.    
  5.     return [[retStr retain] autorelease];    
  6. }    
  7.    
  8. // 使用ARC    
  9.    
  10. -(NSString *)stringTest    
  11. {    
  12.     __autoreleasing NSString *retStr = [NSString alloc] initWithString:@”test”];    
  13.    
  14.     return retStr;    
  15. }    

 

 

纵使当方法的参数是id*,且要方法返回时对象吃autoreleased,那么下该重大字。

 

总结

今日,我们看出了基本的ARC使用规则

  •     代码中未能够使retain, release,
    retain, autorelease
  •    
    不更载dealloc(如果是放对象内存以外的处理,是可重载该函数的,但是未可知调用[super
    dealloc])
  •     不能够采用NSAllocateObject,
    NSDeallocateObject
  •    
    不克于C结构体中使对象指针
  •     id与void
    *个中的只要cast时要因此特定的计(__bridge关键字)
  •    
    不可知使NSAutoReleasePool、而需@autoreleasepool块
  •     不克采取“new”开始的特性名称
    (如果利用会产生下的编译错误”Property’s synthesized getter follows
    Cocoa naming convention for returning ‘owned’ objects”)

 

 


 

 

ARC工作规律是在编译程序的时段是因为xCode将内存操作的代码(如:retain,release
和 autorelease)自动添加至得之位置。

 

ARC
只能于iOS4 和iOS5臻运,weak refrences
只能当iOS5上运,并且不得不是工程于ARC管理内存的时才能够因此。
一味版的工程是好变成为用ARC的工,转换规则包括:

        1.失去丢所有的retain,release,autorelease

        2.把NSAutoRelease替换成@autoreleasepool{}块

        3.管assign的特性改为weak

行使ARC的一对强制规定

       
1.免克直接调用dealloc方法,不可知调用retain,release,autorelease,reraubCount方法,包括@selector(retain)的艺术吗要命

       
2.截图租户事故发布dealloc方法来管理有资源,但无可知用来放实例变量,也无能够当dealloc方法中去丢[super
dealloc]方,在ARC下父类的dealloc同样由编译器来机关就

        3.Core
Foundation类型的目标任然可以就此CFRetain,CFRelease这些措施

        4.勿能够于使用NSAllocateObject和NSDeallocateObject对象

       
5.请勿能够以c结构体中使对象指针,如果发生像样功能可创造一个Objective-c类来保管这些目标

        6.在id和void *次无简便的转换方法,同样以Objective-c和core
Foundation类型之间的转换都需要使用编译器制定的易函数

       
7.无可知重复用NSAutoreleasePool对象,ARC提供了@autoreleasepool片来取代它,这样更有效率

        8.免能够采用外存存储区(不克还采取NSZone)

        9.不可知为new为初步为一个性质命名

        10.声明outlet时一般应有采取weak,除了针对StoryBoard
这样nib中间的顶层对象要用strong

        11.weak 相当给老版的assign,strong相当于retain

本着工程中之单个文件制定不行使ARC的道:在targets的build
phases选项下Compile
Sources下摘要无使arc编译的文件,双击它,输入-fno-objc-arc即可

 

 

 

 

属性值 关键字 所有权
strong __strong
weak __weak
unsafe_unretained __unsafe_unretained
copy __strong
assign __unsafe_unretained
retain __strong

 

strong

 

该属性值对应 __strong 关键字,即该属性所声明的变量将改为目标的主人。

 

weak

 

该属性对应 __weak 关键字,与 __weak
定义之变量一致,该属性所声明的变量将无目标的所有权,并且当目标被破弃之后,对象将给机关赋值nil。

 

与此同时,delegate 和 Outlet 应该用 weak 属性来声称。同时,如达到同一扭曲介绍的
iOS 5 之前的版是没有 __weak 关键字之,所以 weak
属性是休克利用的。这种气象我们利用 unsafe_unretained。

 

unsafe_unretained

 

等效于__unsafe_unretaind关键字声明的变量;像面说明的,iOS
5之前的体系就此该属性代替 weak 来运。

 

copy

 

暨 strong 的分别是声称变量是拷贝对象的主人。

 

assign

 

一般Scalar Varible用该属性声明,比如,int, BOOL。

 

retain

 

拖欠属性和 strong 一致;只是可读性更胜似片。

 

宣读写相关的属于性 (readwrite,
readonly)

 

读写相关的性能有 readwrite 和 readonly
两栽,如果采取ARC之后,我么需要小心一下 readonly 属性的用。

 

随下面的变量声明。

 

  1. @property (nonatomic, readonly) NSString *name;
     

 

貌似宣称也 readonly
的变量按理说应该不欲持有所有权了,但是当ARC有效之情状下,将出现下面的错误信息

 

 

 

 “ARC forbids synthesizing a property of an Objective-C object with unspecified ownership or storage attribute


如果定义了ARC有效,那么得要有所有者属性的概念;所以我们的代码改化这样,就OK了

 

 

  1. @property (nonatomic, strong, readonly) NSString *name; 

 

而出好几,Scalar Varible的变量缺省还起 assign
的习性定义,所以无待给他俩单独的明示声明了。

 

 

来源:http://justcoding.iteye.com/blog/1391548

相关文章