ARC简介以及工程中ARC与非ARC的混合

ARC与非ARC在一个项目中同时使用,

1,选择项目中的Targets,选中你所要操做的Target,
2,选Build Phases,在其中Complie Sources中选择须要ARC的文件双击,并在输入框中输入:-fobjc-arc,若是不要ARC则输入:-fno-objc-arc
html

混用没有问题,没有用ARC的代码继续坚持谁申请谁释放就行了。之前的库没有时间重写,都采用这种方法。

并且不知道你用的是什么第三方代码,通常来讲,如今不多有arc only的代码,大部分都是用一些宏来让代码能够同时适应arc和非arc的(用#if __has_feature(objc_arc)判断)。若是代码量不大,能够考虑本身进行改写
ios

ARC是什么objective-c

ARC是iOS 5推出的新功能,全称叫 ARC(Automatic Reference Counting)。简单地说,就是代码中自动加入了retain/release,原先须要手动添加的用来处理内存管理的引用计数的代码能够自动地由编译器完成了。app

该机能在 iOS 5/ Mac OS X 10.7 开始导入,利用 Xcode4.2 可使用该机能。简单地理解ARC,就是经过指定的语法,让编译器(LLVM 3.0)在编译代码时,自动生成实例的引用计数管理部分代码。有一点,ARC并非GC,它只是一种代码静态分析(Static Analyzer)工具。函数

ARC是编译器LLVM 3.0的新功能,而非iOS,所以ARC支持 Mac OS X v10.6 v10.7 (64-bit applications) 以及 iOS 4 iOS 5. (遗憾的是,weak reference 是runtime属性,所以 不支持 iOS 4 和 Mac OS X v10.6。工具

你不能使用new开头的变量post

ARC只对objective-c对象起做用,对于Core Foundation 之类,你仍然须要本身手动释放。学习

ARC的优点:
一、再也不须要考虑retain、release的问题,咱们得以在更高的层面考虑问题,而不是纠结于何时释放的细节。
二、zeroing-weak reference , 咱们终于能够摆脱烦人的 zombies 对象,想一想delegate机制,当delegate对象deallocated以后,你再向它发消息会发生什么?如今当你调用 self.delegate 时,若是它被释放,那么这个弱指针会自动变为 nil 。
三、ARC给人的感受是直接存对象到变量里面。所以以前一段不可能的代码如今也变为可能:
ui

 

变化点url

经过一小段代码,咱们看看使用ARC先后的变化点。

@interface NonARCObject : NSObject { NSString *name; } -(id)initWithName:(NSString *)name; @end @implementation NonARCObject -(id)initWithName:(NSString *)newName { self = [super init]; if (self) { name = [newName retain]; } return self; } -(void)dealloc { [name release]; [Super dealloc]; } @end
@interface ARCObject : NSObject { NSString *name; } -(id)initWithName:(NSString *)name; @end @implementation ARCObject -(id)initWithName:(NSString *)newName { self = [super init]; if (self) { name = newName; } return self; } @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"的错误信息。

 

这个时候,能够将项目编译设置中的“Objectice-C Auto Reference Counteting”设为NO。以下所示。

 

若是只想对某个.m文件不适应ARC,能够只针对该类文件加上 -fno-objc-arc 编译FLAGS,以下图。

 

 

ARC基本规则

    retain, release, autorelease, dealloc由编译器自动插入,不能在代码中调用

    dealloc虽然能够被重载,可是不能调用[super dealloc]

因为ARC并非GC,并须要一些规则让编译器支持代码插入,因此必须清楚清楚了这些规则后,才能写出健壮的代码。

 

Objective-C对象

 

ObjectiveC中的对象,有强参照(Strong reference)和弱参照(Weak reference)之分,当须要保持其余对象的时候,须要retain以确保对象引用计数加1。对象的持有者(owner)只要存在,那么该对象的强参照就一直存在。

 

对象处理的基本规则是

 

  只要对象的持有者存在(对象被强参照),那么就可使用该对象

    对象失去了持有者后,即被破弃

 

强参照 (Strong reference)

(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)

(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 开始导入。因为该类型不影响对象的生命周期,因此若是对象以前就没有持有者,那么会出现刚建立就被破弃的问题,好比下面的代码。

NSString __weak *string = [[NSString alloc] initWithFormat:@"First Name: %@", [self firstName]]; 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。他被常常用于函数有值参数返回时的处理,好比下面的例子。

- (void) generateErrorInVariable:(__autoreleasing NSError **)paramError { .... *paramError = [[NSError alloc] initWithDomain:@"MyApp" code:1 userInfo:errorDictionary]; } .... { NSError *error = nil; [self generateErrorInVariable:&error]; NSLog(@"Error = %@", error); }

又如函数的返回值是在函数中申请的,那么但愿释放是在调用端时,每每有下面的代码。

-(NSString *)stringTest
{
    NSString *retStr = [NSString stringWithString:@"test"]; return [[retStr retain] autorelease]; }
// 使用ARC

-(NSString *)stringTest
{
    __autoreleasing NSString *retStr = [NSString alloc] initWithString:@"test"];

    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”)

 

Part 1:
http://www.raywenderlich.com/5677/beginning-arc-in-ios-5-part-1
Part 2:
http://www.raywenderlich.com/5773/beginning-arc-in-ios-5-tutorial-part-2

Apple 文档
http://developer.apple.com/library/IOs/#releasenotes/ObjectiveC/RN-TransitioningToARC/_index.html

相关文章
相关标签/搜索