Objective-C中的内存管理,也就是引用计数, 可以用如下方式进行思考:
- 自己生成的对象, 自己持有.
- 非自己生成的对象, 自己也能持有.
- 不再需要自己持有的对象时释放对象
- 非自己持有的对象无法释放
“生成”, “持有”, “释放”, “废弃”四个词对应的Objective-C方法如下:
- 生成: alloc/new/copy/mutableCopy 等方法
- 持有: retain方法
- 释放: release方法
- 废弃: dealloc方法
这些内存管理相关的方法, 实际上不包括在语言本身中, 而是包含在Cocoa框架中. Cocoa框架中Foundation框架类库的NSObject类负责进行内存管理.
自己生成并持有对象
使用以下名称开头的方法意味着自己生成的对象只有自己持有:
- alloc
- new
- copy
- mutableCopy
alloc/new示例:
id obj = [[NSObject alloc]init];
id obj = [NSObject new];
copy方法生成不可变的对象, 而mutableCopy生成可变的对象.
非自己生成的对象, 自己也能持有
用alloc/new/copy/mutableCopy之外的方法取得的对象, 自己也能持有:
//取得非自己生成的对象
id obj = [NSMutableArray array];
//此时使用release会crash
//[obj release];
//持有对象
[obj retain];
通过retain
方法, 能持有非自己生成的对象.
不再需要自己持有的对象时释放对象
自己生成持有的对象, 一旦不再需要, 持有者有义务释放该对象. 释放使用release方法.
id obj = [[NSObject alloc]init];
[obj release];
非自己生成,但自己持有的对象, 若使用retain方法持有之后, 不需要时, 也要使用release方法释放.
NSMutableArray *array = [NSMutableArray array];
[array retain];
[array release];
那么调用[NSMutableArray array]
方法取得对象存在, 但自己不持有对象, 是怎么实现的呢?
- (id)object {
//持有对象
id obj = [[NSObject alloc]init];
//取得的对象存在, 但自己不持有对象
[obj autorelease];
return obj;
}
使用autorelease
方法可以取得对象, 但自己不持有对象. autorelease
能使对象在超出指定的生存范围时能够自动正确的释放(release).
无法释放非自己持有的对象
如果应用中释放了非自己所持有的对象就会造成崩溃, 最常见的情况就是过度释放:
id obj = [[NSObject alloc]init];
[obj release];
//下面会引起崩溃
//[obj release];
或
//取得非自己生成的对象
id obj = [NSMutableArray array];
//此时使用release会crash
//[obj release];