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

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

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

而且不知道你用的是什么第三方代码,一般来说,现在很少有arc only的代码,大部分都是用一些宏来让代码可以同时适应arc和非arc的(用#if __has_feature(objc_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是编译器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开头的变量

ARC只对objective-c对象起作用,对于Core Foundation 之类,你仍然需要自己手动释放。

ARC的优势:
1、不再需要考虑retain、release的问题,我们得以在更高的层面考虑问题,而不是纠结于什么时候释放的细节。
2、zeroing-weak reference , 我们终于可以摆脱烦人的 zombies 对象,想想delegate机制,当delegate对象deallocated之后,你再向它发消息会发生什么?现在当你调用 self.delegate 时,如果它被释放,那么这个弱指针会自动变为 nil 。
3、ARC给人的感觉是直接存对象到变量里面。因此之前一段不可能的代码现在也变为可能:

变化点

通过一小段代码,我们看看使用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

ARC简介以及工程中ARC与非ARC的混合(转)的更多相关文章

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

    Piosa 博客园 博问 闪存 首页 新随笔 联系 管理 订阅 随笔- 79  文章- 0  评论- 13    ARC简介以及工程中ARC与非ARC的混合   ARC与非ARC在一个项目中同时使用, ...

  2. 转:在支持ARC工程中编译不支持ARC的文件

    转:http://blog.csdn.net/duxinfeng2010/article/details/8709697 实践总结:-fno-objc-arc 设置 解决了 旧代码中存在 releas ...

  3. 如何在ARC代码中混编非ARC代码

    “ios中如果arc和非arc文件混编,可以在build parses中指定compile flags,如果arc文件设为"-fobjc-arc",非arc文件设为"-f ...

  4. [ios]如何在ARC代码中混编非ARC代码

    参考 :http://blog.sina.com.cn/s/blog_b595ce9e0101nvvn.html “ios中如果arc和非arc文件混编,可以在build parses中指定compi ...

  5. iOS arc下控制某一文件为非arc

    选中文件加上编译参数 -fno-objc-arc即可.

  6. arc项目中使用非arc文件

    因为之前没有ARC机制,好多比较好的类库都是使用的非ARC,或是有些大牛还是不喜欢用ARC,封装的类也是非ARC的,想要在自己的ARC项目中使用这些非ARC类库,只需要简单的设置一下就可以了. 1.在 ...

  7. 【iOS开发】在ARC项目中使用非ARC文件

    ARC的出现应该说是开发者的一大福利,苹果是推荐使用的,但是因为之前没有ARC机制,好多比较好的类库都是使用的非ARC,或是有些大牛还是不喜欢用ARC,封装的类也是非ARC的,想要在自己的ARC项目中 ...

  8. iOS 非ARC基本内存管理系列 -手把手教你ARC——iOS/Mac开发ARC入门和使用(转)

    手把手教你ARC——iOS/Mac开发ARC入门和使用 Revolution of Objective-c 本文部分实例取自iOS 5 Toturail一书中关于ARC的教程和公开内容,仅用于技术交流 ...

  9. ARC工程中添加非ARC文件

    转载自:http://blog.csdn.net/zhenweicao/article/details/16988543 分类: IOS2013-11-27 17:02 626人阅读 评论(0) 收藏 ...

随机推荐

  1. uboot下的网络终端/控制台

    许多linux设备可能没有外置串口,这是就需要一个网络终端来在uboot下操作设备,如升级镜像等. uboot下的网络终端为netconsole,代码drivers/net/netconsole.c. ...

  2. Linux系统中的以太网连接

    1.在Linux中,以太网连接接口被命令为:eth0,eth1等,其中0,1表示网卡编号. 2.lspci来查看网卡硬件信息(USB则是lsusb) 3.ifconfig来查看接口信息 ifconfi ...

  3. Java实现Kmeans算法

    Kmeans算法的Java实现.源代码放在github上,大家有兴趣能够下下来看看, 源代码地址: https://github.com/l294265421/algorithm-kmeans 实现该 ...

  4. android开发(31) 动画演示 - 从页面底部向上弹出dialog,消失时逐渐向下

    我想实现一个效果,从底部向上逐渐弹出.如下图所示: 1.点击 显示 按钮时,一个dialog对话框从底部慢慢向上弹出. 2.关闭dialog时, dialog缓慢的移动向底部消失.很平滑的效果.   ...

  5. MVC教程七:扩展HtmlHelper方法

    在上一篇文章的最后,列出了一些常见的HtmlHelper的方法,这些都是ASP.NET MVC已经定义好的,如果我们想自己定义一个HtmlHelper方法可以吗?答案是肯定的,那么如何自定义一个Htm ...

  6. tabs 标签样式

    http://www.jq22.com/jquery-info17973 http://www.jq22.com/demo/elementTab201801262311/ 插件描述:基于element ...

  7. Vue 获取自定义属性的值

    在jquery中,如果要获取 data-*** 的值可以通过 $('目标元素').data('属性名') 来获取. 在Vue中如何获取该值呢? 1.换个思路,作为参数传递. 如下代码: <but ...

  8. hibernate整合进spring后的事务处理

    单独使用hibernate处理事务 本来只用hibernate开发,从而可以省了DAO层实现数据库访问和跨数据库,也可以对代码进行更好的封装,当我们web中单独使用hibernate时,我们需要单独的 ...

  9. java_review_point

    Math.atan2() 这个函数很常用,可以实现利用点的坐标x,y来计算点的弧度值. 本质来说,是一个反tan函数. this 指类的对象,区别于局部的变量. static方法可以在类里面任意调用, ...

  10. 关于Unity中Vector2和Vector3的使用

    Vector2是用来定义和描述2D游戏内部的一些参数,像刚体的速度等等 Vector3是 1.鼠标点击屏幕后要转化为3D坐标的时候用到的定义和描述 2.两个物体之间的相对距离,或者说偏移量的变量类型