引用计数的原则
- 自己生成的对象自己持有
- 非自己生成的对象自己也可以持有
- 不再需要自己持有的对象时释放
- 非自己持有的对象无法释放
案例:
/*
* 自己生成并持有对象
*/
id obj1 = [[NSObject alloc] init];
/*
* 自己持有对象
*/
[obj1 release];
/*
* 释放对象
针仍然被保留在变量obj1中
* 但对象一经释放绝对不能被访问
* /
/*
* 取得非自己生成的对象
*/
id obj2 = [NSMutableArray array];
/*
* 自己不持有对象
*/
[obj2 retain]; //ARC不需要这个操作,编译器会自动帮我们实现。而MRC下需要。
/*
* 自己持有对象
*/
[obj2 release];
/*
* 释放对象
*/
那么[NSMutableArray array]这个方法是如何实现取得对象存在,而不持有对象的呢。其实是用到了autorelease方法。
-(id) object {
id obj = [[NSObject alloc] init];
[obj autorelease];
return obj;
}
autorelease与release的区别在于。release一个对象,该对象立马释放,而autorelease一个对象,该对象注册到autoreleasepool中,pool结束时自动调用release。
- (id) autorelease {
[NSAutoreleasePool addObject:self];
}
因此上面的代码可以如下表示
NSAutoreleasePool *pool = [[NSAutoReleasePool alloc]init];
id obj = [[NSObject alloc] init];
[obj autorelease];
[pool drain];
autoreleasepool是跟NSRunLoop联系在一起的。NSRunLoop每次循环过程中NSAutoreleasePool对象被生成或被废弃。
另外还有一点就是当有大量的autorelease对象生成,而没有被释放时,就会造成内存不足。比如
for (int i = 0; i < 图象数; ++i) {
/*
* 读入大量图像
* 大量产生autoreleae对象
* 没有释放造成内存不足
* /
}
解决方案就是在适当的地方自己生成、持有、废弃autoreleasepool对象
for (int i = 0; i < 图象数; ++i) {
NSAutoreleasePool *pool = [[NSAutoReleasePool alloc]init];
/*
* 读入大量图像
* 大量产生autoreleae对象
* /
[pool drain];
/*
* autorelease对象被释放
*/
}