一、基础概念:
- 引用计数–ARC(automatic Reference Counting)指内存管理中对引用采取计数的技术。
- Ojective-C中的内存管理,也就是引用计数。
例:例如办公室的照明管理
二、内存管理的思考方式
对象操作与Objective-C方法的对应
- 自己生成的对象,自己所持有
/*
* 自己生成并持有对象
*/
id obj = [[NSObject alloc] init];
/*等同于*/
id obj = [NSObject new];
/*
copy方法--利用基于NSCopying方法约定,由各类实现的 copyWithZone:方法生成并持有对象的副本。
mutableCopy方法--利用基于NSMutableCopying方法约定,由各类实现的mutableCopyWithZone:方法生成并持有对象的副本。
两者的区别:
copy方法生成不可变更的对象
mutableCopy方法生成可变更的对象
*/
- 非自己生成的对象,自己也能持有
/*
alloc/new/copy/mutableCopy等方法取得对象,是自己生成并持有。
除了以上方法生成的对象不是自己生成对象,但是可以持有
*/
/*
* 取得非自己生成并持有的对象
* 取得对象虽然存在,但自己不持有对象
*/
id obj = [NSMutableArray array];
/*
* 自己持有对象
* 通过retain方法,非自己生称的对象跟用
alloc/new/copy/mutableCopy方法生成并持有的对象一样,称为了自己所持有的
*/
[obj retain];
- 不再需要自己持有的对象时释放
/*
* 自己持有的对象,一旦不再需要。持有者有义务释放该对象。释放使用release方法。
*/
/*
* 自己生成并持有对象
*/
id obj = [[NSObject alloc] init];
/*
* 释放对象
*
* 指向对象的指针仍然被保留在变量obj中(称为僵尸对象),貌似能够访问
* 但对象一经释放绝对不可访问,访问已经释放的对象(僵尸对象),会造成程序崩溃
*
* 用alloc方法由自己生成并持有的对象就通过release方法释放了。
* 自己生成而非自己所持有的对象,若用retain方法变为自己持有,也同样可以用release方法释放。
*/
[obj release];
/*
* 用alloc方法由自己生成并持有的对象就通过release方法释放了。
* 自己生成而非自己所持有的对象,若用retain方法变为自己持有,也同样可以用release方法释放。
*/
/*
* 取得非自己生成并持有的对象
* 取得的对象存在,但自己不持有对象
*/
id obj = [NSMutableArray array];
// 自己持有对象
[obj retain];
/*
* 释放对象
* 对象不可再被访问
*/
[obj release];
/*
* 用alloc/new/copy/mutableCopy方法生成并持有的对象,或者用retain方法持有的对象,一旦不再需要,务必要用release方法进行释放。
*/
/*
* 如果要用某个方法生成对象,并将其返回给该方法的调用方。代码如下:
*/
-(id)allocObject
{
// 自己生成并持有对象
id obj = [[NSObject alloc] init];
/*
*
*/
return obj;
}
// 调用allocObject方法
// 取得非自己生成并持有的对象
id obj1 = [obj0 allocObject];
/*
* 例如[NSMutableArray array];
* 使得取得对象存在,但自己不持有对象
* 根据命名规则,不能使用以alloc/new/copy/mutableCopy开头的方法名。
* 实现方法:
*/
-(id)object
{
id obj = [NSObject alloc] init];
// 取得的对象存在,但自己不持有对象
[obj autorelease];
return obj;
}
/*
* 取得的对象存在,但自己不持有对象
*/
id obj1 = [obj0 object];
/*
也可以使用retain使自己持有对象
[obj1 retain];
*/
注:release和autorelease的区别
例如:NSMutableArray类的array类方法等可以取得谁都不持有的对象,这些方法都是通过autorelease而实现的。
- 非自己持有的对象无法释放
/*
1、对于用alloc/new/copy/mutableCopy方法生成并持有的对象,或是用retain方法持有的对象,由于持有者是自己,所以在不需要该对象时需要将其释放。
2、而由此以外所得到的对象绝对不能释放,在应用程序中释放了非自己所持有的对象就会造成崩溃。
3、释放之后再次释放以非自己持有的对象或者访问已经释放的对象,都会导致程序崩溃
*/
id obj = [[NSObject alloc] init];
[obj release]; // 对象已经释放,不再持有该对象
[obj release]; // 再次释放不再持有的对象,崩溃
/*
* 取得的对象存在,但自己不持有对象时释放,程序崩溃
*/
id obj1 = [obj0 object];
[obj1 release];
注:这些关于Object-C内存管理的方法,实际上不包括在该语言中,而是包括在Cocoa框架中用于OS X、iOS应用开发。Cocoa框架中Foundation框架类库的NSObject类负担内存管理的职责。Objective-C内存管理中的alloc/retain/release/dealloc方法分别指代NSObject类的alloc类方法、retain实例方法、release实例方法和dealloc实例方法。