iOS应用开发——ARC

原文链接:http://www.yifeiyang.net/development-of-the-iphone-simply-1/


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







我们之前使用Objective-C中内存管理规则时,往往采用下面的准则
  • ✿ 生成对象时,使用autorelease
  • ✿ 对象代入时,先autorelease后再retain
  • ✿ 对象在函数中返回时,使用return [[object retain] autorelease];

而使用ARC后,我们可以不需要这样做了,甚至连最基础的release都不需要了。

使用ARC的好处


使用ARC有什么好处呢?

  • ✿看到上面的例子,大家就知道了,以后写Objective-C的代码变得简单多了,因为我们不需要担心烦人的内存管理,担心内存泄露了
  • ✿ 代码的总量变少了,看上去清爽了不少,也节省了劳动力
  • ✿ 代码高速化,由于使用编译器管理引用计数,减少了低效代码的可能性

不好的地方


  • ✿记住一堆新的ARC规则 — 关键字及特性等需要一定的学习周期
  • ✿ 一些旧的代码,第三方代码使用的时候比较麻烦;修改代码需要工数,要么修改编译开关

ARC基本规则


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

由于ARC并不是GC,并需要一些规则让编译器支持代码插入,所以必须清楚清楚了这些规则后,才能写出健壮的代码。

Objective-C对象


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

对象处理的基本规则是
  • ✿ 只要对象的持有者存在(对象被强参照),那么就可以使用该对象
  • ✿ 对象失去了持有者后,即被破弃

引用关键字

ARC中关于对象的引用参照,主要有下面几关键字。使用strong, weak, autoreleasing限定的变量会被隐式初始化为nil。

  • __strong

变量声明缺省都带有__strong关键字,如果变量什么关键字都不写,那么缺省就是强参照。

  • __weak

上面已经看到了,这是弱参照的关键字。该概念是新特性,从 iOS 5/ Mac OS X 10.7 开始导入。由于该类型不影响对象的生命周期,所以如果对象之前就没有持有者,那么会出现刚创建就被破弃的问题。


如果编译设定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。他被经常用于函数有值参数返回时的处理。


总结

今天,我们看到了基本的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”)


你可能感兴趣的:(ios)