1.1 什么是自动引用计数
自动引用计数(ARC,Automatic Reference Counting)是指内存管理中对引用采取自动计数的技术。在Objective-C中采用ARC机制,让编译器进行内存管理。无需再次键入retain或者release代码,这在降低程序崩溃、内存泄漏等风险的同时,很大程度上减少了开发程序的工作量。编译器完全清楚目标对象,并能立刻释放那些不能再被使用的对象。如此一来,应用程序将具有可预测性,且能流畅运行,速度也将大幅提升。
1.2 内存管理的思考方式
① 自己生成的对象,自己所持有。
② 非自己生成的对象,自己也能持有。
③ 不再需要自己持有的对象时释放。
④非自己持有的对象无法释放。
以上有关Objective-C内存管理的方法,实际上不包括在该语言中,而是包含在Cocoa框架中用于OS 、iOS应用开发。Cocoa框架中Foundation框架类库的NSObject类担负内存管理的职责。
非自己生成的对象也能持有
id obj = [NSMutableArray array]; // 取得对象存在, 但自己并不持有对象
[obj retain]; // 自己持有对象
无法释放非自己持有的对象
id obj = [NSMutableArray array]; // 取得对象存在, 但自己并不持有对象
[obj release]; // 释放了非自己持有的对象!会导致应用程序崩溃
1.3 autorelease
autorelease就是自动释放。这很像C语言中的局部变量的特性。autorelease会像C语言的局部变量那样来对待对象实例。当超出其作用域时,对象实例的release方法被调用。另外,同C语言不同的是,编程人员可以设定变量的作用域。
autorelease的具体使用方法如下:
① 生成并持有NSAutoreleasePool对象;
② 调用已分配对象的autorelease实例方法;
③ 废弃NSAutoreleasePool对象。
NSAutoreleasePool对象的生存周期相当于C语言变量的作用域。对于所有调用过autorelease实例方法的对象,在废弃NSAutoreleasePool对象时,都将调用release实例方法如上图所示。用源码表示如下:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
id obj = [[NSObject allic] init];
[obj autorelease];
[pool drain];
在Cocoa框架中,相当于程序主循环的NSRunLoop或者在其他程序可运行的地方,对NSAutoreleasePool对象进行生成、持有和废弃处理。因此,应用程序开发者不一定非得使用NSAutoreleasePool来进行开发工作。
另外,在Cocoa框架中也有很多类方法用于返回autorelease的对象。比如NSMutableArray类的arrayWithCapacity类方法。
id array = [[NSMutableArray arrayWithCapacity: 1]];
此源码等同于以下源码。
id array = [[[NSMutableArray alloc] initWithCapacity: 1] autorelease];
问题:如果autorelease NSAutoreleasePool对象会如何?
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[pool autorelease];
答案:会发生异常
通常在使用Objective-C,也就是Foundation框架时,无论调用哪一个对象的autorelease实例方法,实现上市调用的都是NSObject类的autorelease实例方法。但是对于NSAutoreleasePool类,autorelease实例方法已被该类重载,因此运行时就会出错。