iOS应用开发:什么是A普拉多C

 

ARC是什么

ACR-VC是iOS 5推出的新效能,全称叫 A宝马7系C(Automatic Reference
Counting)。不难地说,就是代码中自行进入了retain/release,原先须求手动添加的用来拍卖内部存款和储蓄器管理的引用计数的代码能够自动地由编写翻译器完结了。

该机能在 iOS 5/ Mac OS X 10.7 初阶导入,利用 Xcode4.2
能够选拔该意义。简单地领略A索罗德C,正是通过点名的语法,让编写翻译器(LLVM
3.0)在编译代码时,自动生成实例的引用计数管理有个别代码。有好几,A福睿斯C并不是GC,它只是一种代码静态分析(Static
Analyzer)工具。

 

变化点

经过一小段代码,我们看看使用ALacrosseC前后的变化点。

 

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];

而利用A酷威C后,大家能够不必要这么做了,甚至连最基础的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的好处

利用ALANDC有何样好处呢?

  •    看到下面的事例,大家就知晓了,未来写Objective-C的代码变得简单多了,因为大家不须求操心烦人的内部存款和储蓄器管理,担心内部存款和储蓄器败露了
  •    代码的总量降少了,看上去清爽了过多,也节省了劳引力
  •    代码高速化,由于采取编写翻译器管理引用计数,减弱了不算代码的只怕

 

倒霉的地点

  •    记住一堆新的A哈弗C规则 — 关键字及特色等急需肯定的就学周期
  •  
     一些旧的代码,第③方代码应用的时候相比劳碌;修改代码须求工数,要么修改编写翻译开关

至于第③点,由于 XCode4.2 中缺省ATucsonC便是 ON
的状态,所以编写翻译旧代码的时候往往有”Automatic Reference Counting
Issue”的错误音讯。

 

图片 3

 

其一时半刻候,能够将品种编写翻译设置中的“Objectice-C Auto Reference
Counteting”设为NO。如下所示。

 

图片 4

 

假诺只想对某些.m文件不适应ARC,能够只针对此类文件加上 -fno-objc-arc
编写翻译FLAGS,如下图。

 

图片 5

 

A卡宴C基本规则

  •     retain, release, autorelease,
    dealloc由编译器自动插入,无法在代码中调用
  •    
    dealloc即便能够被重载,可是无法调用[super dealloc]

是因为A路虎极光C并不是GC,并索要部分规则让编写翻译器帮衬代码插入,所以必须知道知道了那些规则后,才能写出健康的代码。

 

Objective-C对象

ObjectiveC中的对象,有强参照(Strong reference)和弱参照(Weak
reference)之分,当必要保持其余对象的时候,供给retain以保证指标引用计数加1。对象的全部者(owner)只要存在,那么该目的的强参照就直接存在。

对象处理的大旨规则是

  •     只要对象的主人存在(对象被强参照),那么就足以采取该目的
  •     对象失去了主人后,即被破弃

 

强参照 (Strong reference)

 

图片 6

 

(s1)

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

(s2)

那里将firstName代入到aName中,即aName也改为了@”natsu”字符串对象的持有者,对于该对象,aName也是Strongreference。

(s3)

那边,改变firstName的始末。生成新的字符串对象”maki”。这时候firstName成为”maki”的主人,而@”natsu”的全体者唯有aName。每一种字符串对象都有各自的持有者,所以它们都在内部存款和储蓄器中都存在。

(s4)

日增新的变量otherName,
它将成为@”maki”对象的另二个主人。即NSString类型对象的Strongreference。

(s5)

将otherName代入到aName,这时,aName将成为@”maki”字符串对象的全数者。而目的@”natsu”已经没有主人了,该指标将被破弃。

 

弱参照 (Weak reference)

接下去大家来探视弱参照 (Weak reference) 的利用办法。

 

图片 7

 

(w1)

与强参照格局同样,firstName作为字符串对象@”natsu”的持有者存在。即是该NSString类型对象的Strongreference。

(w2)

利用首要字__weak,表明弱参照weakName变量,将firstName代入。那时weakName尽管参照@”natsu”,但仍是Weak
reference。即weakName尽管能收看@”natsu”,但不是其主人。

(w3)

firstName指向了新的对象@”maki”,成为其主人,而指标@”natsu”因为从没了主人,即被破弃。同时weakName变量将被活动代入nil。

 

引用关键字

ALX570C中关于指标的引用参照,重要有上面几关键字。使用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,那么使用该重庆大学字。

 

总结

前些天,大家见到了大旨的A牧马人C使用规则

  •     代码中不能够使用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”)

 

 


 

 

APRADOC工作规律是在编写翻译程序的时候由xCode将内部存款和储蓄器操作的代码(如:retain,release
和 autorelease)自动添加到须要的职务。

 

A纳瓦拉C
只可以在iOS4 和iOS5上运用,weak refrences
只万幸iOS5上行使,并且只可以是工程在A兰德锐界C管理内部存款和储蓄器的时候才能用。
老版本的工程是足以转换到使用A福睿斯C的工程,转换规则包涵:

        1.去掉全体的retain,release,autorelease

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

        3.把assign的性质改为weak

应用A福睿斯C的有个别威吓规定

       
1.无法一直调用dealloc方法,无法调用retain,release,autorelease,reraubCount方法,包蕴@selector(retain)的方法也不行

       
2.截图租户事故发表dealloc方法来保管有个别能源,但不能够用来刑释实例变量,也无法在dealloc方法里面去掉[super
dealloc]艺术,在A奥迪Q5C下父类的dealloc同样由编写翻译器来机关达成

        3.Core
Foundation类型的靶子任然能够用CFRetain,CFRelease那个主意

        4.不能够在选用NSAllocateObject和NSDeallocateObject对象

       
5.不可能在c结构体中采取对象指针,如若有像样功能能够创设3个Objective-c类来治本这个指标

        6.在id和void *里面一向不简便的转换方法,同样在Objective-c和core
Foundation类型之间的变换都急需动用编写翻译器制定的转换函数

       
7.不可能再接纳NSAutoreleasePool对象,AGL450C提供了@autoreleasepool块来代替它,那样尤其有效能

        8.无法采取内部存款和储蓄器存储区(不能够再利用NSZone)

        9.不可能以new为早先给一特质量命名

        10.申明outlet时相似应当接纳weak,除了对StoryBoard
那样nib中间的顶层对象要用strong

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

对工程中的单个文件制定不选择ALANDC的艺术:在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 属性来声称。同时,如上3次介绍的
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
三种,假使运用APAJEROC之后,作者么须要小心一下 readonly 属性的接纳。

 

比如下边包车型客车变量证明。

 

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

 

相似宣称为 readonly
的变量按理说应该不需求持有全数权了,不过在ALacrosseC有效的景色下,将面世下边包车型客车错误信息:

 

 

 

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


假若定义了A中华VC有效,那么必须求有全部者属性的概念;所以大家的代码改成那样,就OK了

 

 

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

 

不过有几许,Scalar Varible的变量缺省都有 assign
的性质定义,所以不要求给他俩独立的明示注明了。

 

 

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

相关文章