自动引用计数(ARC, Automatic Reference Counting)是指内存管理中对引用采取自动计数的技术。
新一代的Apple LLVM编译器中设置ARC为有效状态,就无需再次键入retain或者是release代码。在了解并使用ARC技术之前,我们先了解一下在代码中,程序员是如何手工进行内存管理的。
1.1 内存管理的思考方式
“生成”、“持有”、“释放”再加上一个“废弃”,这四个词时objective-c内存管理涉及的4种对象操作。各个词表示的objective-c方法如下表:
对象操作 objective-c方法 生成并持有对象alloc/new/copy/mutableCopy
持有对象 retain方法 释放对象 release方法 废弃对象 dealloc方法
这些有关objective-c的内存管理方法,实际上不包括在该语言种,而是包含在Cocoa框架中用于OS X、iOS应用开发。Cocoa框架种Foundation框架类库的NSObject类担负内存管理的职责,objective-c内存管理种的alloc/retain/release/dealloc方法分别指代NSObject类的alloc类方法、retain实例方法、release实例方法和dealloc实例方法。
自己生成的对象,自己持有
使用alloc/new/copy/mutableCopy方法以及以它们开头的方法生成的对象只有自己持有。(需符合驼峰拼写法(CamelCase)来命名的方法)
非自己生成的对象,自己也能持有
用上述方法以外的方法取得的对象,因为不是自己生成的,所以自己不是该对象的持有这。这时,我们通过retain方法,来使他们成为自己持有的对象。例如:
/* *取得非自己生成并持有的对象 */ id obj = [NSMutableArray array]; /* *取得的对象存在,但自己不持有对象 */ [obj retain]; /* *自己持有对象 */
不再需要自己持有的对象时释放
使用alloc/new/copy/mutableCopy方法生成并持有的对象,或者用retain方法持有的对象,一旦不再需要,务必要用release方法进行释放。
/* *自己生成并持有对象 */ id obj = [[NSObject alloc] init]; /* *自己持有对象 */ [obj release]; /* *释放对象 * *指向对象的指针仍然被保留在变量obj中,貌似能够访问,但是对象一经释放绝对不可访 问 */
非自己生成并持有的对象,若用retain方法变为自己持有,则也同样可以用release方法释放:
/* *取得非自己生成并持有的对象 */ id obj = [NSMutableArray array]; /* *取得的对象存在,但自己不持有对象 */ [obj retain]; /* *自己持有对象 */ [obj release]; /* *释放对象,对象不可再被访问。 */
无法释放非自己持有的对象
非上述方法所得到的对象,不是自己持有,绝对不可以释放。一旦在程序中释放了非自己所有的对象就会造成程序崩溃。例如:
/* *自己生成并持有对象 */ id obj = [[NSObject alloc] init]; /* *自己持有对象 */ [obj release]; /* *对象已释放,不再持有该对象,不能再进行访问 */ [obj release]; /* *释放后再次释放非自己持有的对象! *应用程序崩溃! * *崩溃情况: * 再度废弃已经废弃了的对象时崩溃; * 访问了已经废弃了的对象时崩溃 */
或者在“取得的对象存在,但自己并不持有对象”时释放对象:
id obj1 = [obj0 object]; /* *取得的对象存在,但自己不持有对象 */ [obj1 release]; /* *释放了非自己持有的对象! *程序会崩溃 */
以上四项内容为“引用计数式内存管理”的思考方式。
注:文章内容参考Objective-C 高级编程 iOS与OS X多线程和内存管理一书。