ARC实践
Posted syd_programming
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ARC实践相关的知识,希望对你有一定的参考价值。
一. 什么是引用计数
Objective-C中对对象的内存管理可以用生成、持有、释放、废弃4个词来表示,其中生成就是alloc/new/copy/mutableCopy等方法,持有对象 通过retain来实现,释放对象是release操作,废弃对象是dealloc操作。当对象生成的同时自然也持有该对象。
1. 自己生成并持有对象:
// 生成并持有对象
id obj = [[NSObject alloc] init];
// 或者
id obj = [NSObject new];
2. 持有非自己生成的对象:
// 取得对象
id obj = [NSMutableArray array];
// 持有对象
[obj retain];
在这里,array方法返回一个谁都不持有的对象,它的实现可能是这样:
-(id) array
// 创建并持有对象
id obj = [[NSMutabelArray alloc] init];
// 通过autorelease不持有对象
[obj autorelease];
return obj;
在该实现中,通过autorelease方法不持有对象。3. 持有的对象一旦不再需要就要释放:
[obj release];
这里需要注意,只有自己持有该对象才能释放,释放自己没有持有的对象或者已经释放了的对象会引起程序崩溃。
二. autorelease
Autorelease的使用方法如下:
1. 生成NSAutoreleasePool对象
2. 调用对象的autorelease方法
3. 废弃NSAutorelease对象
autorelease有点像C语言的作用域,对于调用了release方法的对象,在废弃NSAutoreleasePool对象时,都将调用release方法。
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
id obj = [[NSObject alloc]init];
[obj autorelease];
[pool drain];
在类和类的方法中定义的变量要么使用autorelease,要么在 类的dealloc方法 中release它们。
除了alloc、new或copy之外的方法创建的对象都自动声明了autorelease。
三. 理解strong和weak
1. strong指针
NSString* str = self.label.text;
如果此时self.label.text的值是"Test Label"的话,这行代码将使得self.label.text和str 都持有这个字符串。
如果再执行
self.label.text = @"another label";
此时str继续持有"Test Label"这个字符串,而self.label.text将持有"another label"这个字符串。
如果此时str被设置为另外一个值,或者超出了它的作用域,"Test Label"将不会被任何对象持有,它将被释放。
2. weak指针
self.label.text = @"Test Label";
weak NSString* str = self.label.text;
此时str将不持有"Test Label"字符串,该字符串仅被self.label.text持有。
self.label.text = @"another label";
这行代码后,@"Test Label"将不被任何对象持有,将被释放,此时str将为nil.
用weak指针指向新创建的对象将导致该对象被立即释放
id __weak obj = [[NSString alloc] init];
由于新创建的对象没有被任何对象持有,因此将立即释放。
四. ARC实践指南:
1. 原则上所有的实例变量和局部变量都应该是strong的,但对一些UI的property应该使用weak,由于它是被UIWindow所持有的,因此源码中它应该是weak的。具体一点:IBOutlet可以为weak,NSString为copy,Delegate一般为weak,其他的看情况。一般来说,类“内部”的属性设置为strong,类“外部”的属性设置为weak。说到底就是一个归属权的问题。小心出现循环引用导致内存无法释放。
2. 通过weak指针可以解决retain循环问题,即父对象拥有子对象,但子对象不拥有父对象,即子对象拥有一个指向父对象的weak指针。
五. 理解关键字 copy, assign, retain
1. 在属性中加copy,意味着建立一个新对象,这样新旧对象的retainCount都是1。
2. assign可以理解为别名,并不增加retainCount,因此适用于基础数据类型和C数据类型。
3. retain即增加计数,适用于NSObject其他子类。
详细可参见 copy, retain, assign , readonly , readwrite,strong,weak,nonatomic整理
以上是关于ARC实践的主要内容,如果未能解决你的问题,请参考以下文章