且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

iOS Automatic Reference Counting(ARC)

更新时间:2021-07-15 07:49:49

引言:

ARC的全称是Automatic Reference Counting,中文翻译过来是:自动引用计数,是苹果在WWDC2011发布iOS5时随同一起的新特性.其用途是为了加强内容管理的便利性和稳定性.简而言之是为了取代MRC.并且ARC编译时特性,它的性能和MRC不相上下,甚至效率更高,苹果建议所有的开发者都去尝试使用,提高生产效率.本文将对ARC进行一个全面的介绍.


参考资料: 

1:手把手教你ARC——iOS/Mac开发ARC入门和使用

http://onevcat.com/2012/06/arc-hand-by-hand/

2:ARC下dealloc过程及.cxx_destruct的探究

http://blog.sunnyxx.com/2014/04/02/objc_dig_arc_dealloc/

安装:

安装只需要一个步骤:

找到工程的设置项Objective-C Automatic Reference Counting,如下图所示,设置为YES即可

iOS Automatic Reference Counting(ARC)

一般需求你手动开启ARC工程的项目,都是之前用MRC开发的.因为新的工程在建立时,默认都会建议你开启ARC模式.

当开启ARC以后,所有release,retain,等会被编译器提出,此时通过两种方式来对代码进行适配以兼容ARC模式

1:使用Xcode自带的ARC代码转换小工具

打开方式:Edit > Refactor > Convert to Objective-C ARC

iOS Automatic Reference Counting(ARC)

在尝试执行转换工具时,我们可能会遇到一些问题,此时需要去手动修改一些源代码,否则无法完成转换:

iOS Automatic Reference Counting(ARC)

前往issue面板,我们需要找出影响转换工具的代码,像下面这样:

iOS Automatic Reference Counting(ARC)

像图中一样搜索一下 ARC Casting Rules 类型的错误, 因为这些都是需要我们手动去更正的.

产生这个错误的原因通常是因为我们将一个NSObject强行转换成 Core Services对象, 特别是Core Foundation(CF)方面的.

在MRC时代,因为手动管理内存,释不释放是开发者自己说了算,编译器不会关心这些,所以不会报错.

但进入ARC时代以后,编译器需要进一步的确定转换后的释放问题,这里需要用到一个独特的关键字: bridge ,通过 bridge 来转换类型.

好在强大的Xcode可以帮我们辅助的插入这些关键字,加快修改速度,就像下图这样:

iOS Automatic Reference Counting(ARC)

修正完成这些问题以后,再次尝试运行转换工具,不出意外,就会出现一个转换后,预览结果,而我们呢,***是再好好审阅一遍我们转换后的代码,看看有没有哪里不对了.

2:手动更改代码至兼容ARC模式.

3:在iOS项目中经常会用到第三方开源项目,强行将其源代码改为ARC是不明智的,吃力不讨好. 不过我们通过对工程进行一些设定,来让其MRC代码兼容ARC模式
首先选择target,然后选择Build Phases标签,展开Compile Sources;
在相关MRC代码的文件后面(Compile Flags)加入编译选项”-fno-objc-arc
如图:
iOS Automatic Reference Counting(ARC)

反之,如果project是不基于ARC的,就需要对ARC的文件设置:"-fobjc-arc"



使用:





 

二:ARC记录一些零碎细节

1:为 NSMutableArray addObject 时 如果 设置 属性 是copy  add时会crash  用strong

2:关于 dealloc 方法 (摘自ARC完全指南)

启用 ARC 之后,dealloc 方法在大部分时候都不再需要了,因为你不能调用实例对象的 release 方法,也不能调用[super dealloc]。假如原先的dealloc 方法只是释放这些对象,Xcode 就会把 dealloc 方法完全移除。你不再需要手动释放任何实例变量。

如果你的 dealloc 方法处理了其它资源(非内存)的释放,如定时器、CoreFoundation 对象,则你仍然需要在 dealloc 方法中进行手动释放,如 CFRelease(),free()等。这时 Xcode 会保留 dealloc 方法,但是移除所有的 release 和[superdealloc]调用。如下:

- (void)dealloc
{
   AudioServicesDisposeSystemSoundID(soundID); 
} 

3:property 的修饰符总结如下:
strong:等同于"retain",属性成为对象的拥有者
weak:属性是 weak pointer,当对象释放时会自动设置为 nil,记住 Outlet 应该使用 Weak
unsafe_unretained:等同于之前的"assign",只有 iOS 4 才应该使用
copy:和之前的 copy 一样,复制一个对象并创建 strong 关联
assign:对象不能使用 assign,但原始类型(BOOL、int、float)仍然可以使用 



总结: