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前后的变化点。

 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    

 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的好处

下ARC有啊利益也?

  •    看地方的例证,大家便知道了,以后写Objective-C的代码变得简单多矣,因为咱们不需要担心烦人的内存管理,担心内存泄露了
  •    代码的总量变少了,看上去清爽了森,也节了劳动力
  •    代码高速化,由于采用编译器管理引用计数,减少了不算代码的可能性

 

坏的地方

  •    记住一堆放新的ARC规则 — 关键字和特点等要自然之就学周期
  •  
     一些原有的代码,第三正在代码应用的时光可比费心;修改代码需要工数,要么修改编译开关

有关第二触及,由于 XCode4.2 中缺省ARC就是 ON
的状态,所以编译旧代码的时刻往往有”Automatic Reference Counting
Issue”的错误信息。

 ACCESS 1

是上,可以用品种编译设置中的“Objectice-C Auto Reference
Counteting”设为NO。如下所示。

 

ACCESS 2

 

假若只有想对某个个.m文件不适应ARC,可以但对此类文件加上 -fno-objc-arc
编译FLAGS,如下图。

 

ACCESS 3

 

ARC基本规则

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

鉴于ARC并无是GC,并欲有条条框框为编译器支持代码插入,所以要掌握知道了这些规则后,才会写起健康的代码。

 

Objective-C对象

ObjectiveC中之目标,有高参照(Strong reference)和去世参照(Weak
reference)之分,当用保持其他对象的时光,需要retain以确保目标引用计数加1。对象的所有者(owner)只要有,那么该目标的高参照就直接存在。

靶处理的基本规则是

  •     只要对象的持有者在(对象被强参照),那么尽管足以采取该目标
  •     对象失去了主人后,即为破弃

 

强参照 (Strong reference)

 

ACCESS 4

 

(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) 的运用方法。

 

ACCESS 5

 

(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
开始导入。由于此类型不影响对象的生命周期,所以若目标之前便从来不所有者,那么会出现恰恰创立就让破弃的问题,比如下面的代码。

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。他给常用来函数ACCESS有价参数返回时之处理,比如下面的事例。

 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 }    

还要如函数的返回值是以函数中申请之,那么愿意出狱是于调用端时,往往产生下的代码。

 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;    

纵使当方法的参数是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”)

 

相关文章