自动引用计数(ARC)

来源:互联网 发布:放大字软件安卓版 编辑:程序博客网 时间:2024/05/21 00:55

ARC

过去做Objective c开发,我们需要手动管理内存,Objective c 的内存管理原理是引用计数(Reference Count-ing,简写RC),手动管理内存遵循黄金法则(有兴趣的去查一下)。

在Xcode4.2出现了新的内存管理机制,自动引用计数(Automatic Reference Count- ing,简写ARC),注意,是自动引用计数。这种自动管理内存机制跟大家所熟知的GC垃圾回收机制是不一样的,自动管理内存的原理不一样,ARC是LLVM3.0编绎器的特性之一,使用ARC,也就是使用LLVM3.0编绎器编绎程序,编绎器会在需要添加retain或release的地方自动添加(过去需要自己手动添加,有时候还惹来一大堆的内存问题)。

过去在RC机制下,对于内存管理,我们需要关心的是对象的引用计数,而在ARC机制下,也只不过换了个名称,如果我们想继续“手动”管理内存,我们需要关心的是对象的拥有者数量。在RC机制下,当对象的引用计数为0时(当然,在编绎器中去输出对象的引用计数,最小是显示是1),内存被释放回收,在ARC机制下,当对象的拥有者数为0时,系统会自动释放内存并回收,并不需要我们去release对象,这看上去很方便吧。

在ARC机制下,所谓的拥有者数,就是创建一个对象相同的指针并指向该对象即可成为该对象的拥有者, 例如:UIView*firstView=(UIView*)secondView(当然,如果该指针是弱引用则不会成为拥有者,这个概念后面会解释),一个对象可以有多个拥有者。如果要换转成RC机制的话,就变成了UIView* firstView = [(UIView*) secondView  retain]。

ARC的出现,同时也产生了两个新的属性设置,Strong和Weak,在Objective c中Strong声明为强指针,强引用,而Weak则相反(弱指针,弱引用)。当一个指针被声明为Strong时,该指针可以指向某一对象并成为该对象的拥有者,而Weak只能指向对象,但不能成为拥有者,这是赤裸裸的高富帅跟屌丝的对比啊,所以在我看来,我们不妨称Strong指针为“高富帅”指针,而Weak指针,只能当屌丝指针了。好像有点跑题了,言归正传,我们来看一下强弱指针的定义。

强指针:__strong UIView*view;

弱指针:__weak UIView*view;

在前面我讲到,要注意ARC机制是自动引用计数,介绍了强弱指针,跟ARC对于内存的处理方式之后,我们就可以来讨论一下为什么强调ARC机制是自动引用计数了。一般情况下,我们会称ARC机制为自动管理内存,用了ARC就不需要理会内存问题了,妈妈再也不用担心我的内存管理,但我个人认为这是不准确的,或者说不完全的。因为一个iOS App可以占用的内存是有限制的,虽然ARC机制可以为你自动释放内存,但是我们可以从ARC机制管理内存的原理可以看出,如果一个对象存在拥有者,编绎器就不会去释放该对象的内存,所以,当你的程序有着大量的对象一直存在拥有者时,那么,这些对象的内存就会一直不被释放,后果可想而知。由于ARC机制如此,所以,在ARC机制下,我们仍可以“手动”去管理内存。

从ARC机制管理内存的原理可以看出,编绎器释放内存的关键在于对象拥有者数,这与我们过去手动管理内理是如出一辙的,所以,抓住这原理,我们就可以在ARC机制下“手动”管理内存了。我们可以把一些不再用到的强指针设置为nil来减少对象的拥有者数。例:UIView*firstView=(UIView*)secondView;  firstView=nil;当secondView这个对象的拥有者为0时,view_对象所占有的内存就会被编绎器释放并回收,对比我们过去手动管理内存,这和UIView*firstView=[(UIView*)secondView  retain];[firstView release]是一样的。作为一个优秀的程序员,即使是用RC机制,我们也应该把指向已经被释放内存的指针设置为nil,防止野指针的出现。在此,我们也可以看出,Strong,Weak与retain,assign非常相似。

在编绎器的默认情况下,成员变量和局部变量为强指针(局部变量的所有权在方法结束时回收),不需要再去声明,但弱指针就需要我们去声明。ARC机制对于弱指针也是有一些处理的,当弱指针所指向的内存被释放时,该弱指针会被编绎器自动设置为nil,不需要我们手动去设置,这也减轻了我们的负担。

ARC机制管理内存是有范围限制的,ARC机制只会管理Objective c的对象,而对于C或C++的内存,则是ARC机制管理范围之外的,即,C或C++仍需要我们手动去管理内存的,当然,如果我们使用Core Fundation这个框架,也可以通过免费接桥的方式,把Core Fundation的对象的所有权转到Objective c,这样就可以转到ARC机制的管理范围内了(对于接桥这一块,有兴趣或者有需要的,可以到网上找相关的详细资料看),但不是所有都可以通过免费接桥转换。由此,我们也可以看出,ARC机制并非万能。

虽然ARC机制可以帮我们解决那些烦人的内存问题,但同时ARC机制也是有一些限制的。在使ARC机制下,不能将Objective c对象放到C的结构体中。在我们需要获取IB的对象或者自定义理代时,要把属性或者成员变量声明为Weak。ARC机制下把理代声明为Weak,这和RC机制下把理代声明为assign是一样的,目的是为了防止对象间循环引用而导致内存泄漏。由此我们也可以看出,ARC机制跟GC垃圾回收机制是不同的,GC垃圾回收机制在垃圾搜集器可以识别这种循环并释放,但ARC机制不是垃圾回收机制,仍需要手动处理所有权的循环问题,而弱指针(Weak)则可以解决这一循环问题。

ARC机制下可以重写dealloc方法,但不能添加[super dealloc];ARC机制下重写dealloc方法,有时候是很有必要的。停止计时器,反注册通知,测试内存释放等。但你所定义成员变量不再需要在dealloc方法中释放,因为ARC机制还是帮了我们不少忙的,当对象的内存被释放时,对象所有的成员变量也会被释放。

第一次写技术贴,请多提意见,有错有漏的请及时提出,有看不明白的请联系我。

QQ:540537196

邮箱:iosdelpan@163.com

下篇会继续更新ARC机制下的一些应用,block,单例,自动释放池等。