autorelease是苹果引以为傲的地方,它为程序开发人员减轻了很大的开发压力,下面就介绍下autorelease。
autorelease ,顾名思义,就是自动释放,它看上去就像是ARC,其实他更像C语言里面的自动变量(局部变量),
C语言里面的局部变量,就是当变量超出其作用域以后,该自动变量就会被自动抛弃。下面复习下C语言里面的自动变量
-(void)getIt
{
int a =0;
/*
*因为超出变量作用域,
*自动变量“int a”被废弃,不可再访问
*/
}
autorelease的具体使用方法是:1)、生成并持有NSAutoReseasePool对象。2)、调用已分配对象的autorelease实例方法。3)、废弃NSAutoReseasePool对象
-(void)objcAutorelease
{
NSAutoreleasePool * autoreleasePool = [[NSAutoreleasePoolalloc]init];
id objc = [[NSObjectalloc]init];
[objcautorelease];
[autoreleasePooldrain];
/*
*[autoreleasePool drain] 相当于 [objc release];
*自动释放池[autoreleasePool drain]的时候,会给池子里面的对象发送一个release消息,让实例变量执行release方法
*/
}
for (int i =0; i<10000; i++) {
/*
*读入大量图像10000
*由于没有废弃NSAutoreleasePool对象
*最终导致内存不足
*/
}
for (int i =0; i<10000; i++) {
NSAutoreleasePool * autoreleasePool = [[NSAutoreleasePoolalloc]init];
/*
*读入大量图像
*由于没有废弃NSAutoreleasePool对象
*最终导致内存不足
*/
[autoreleasePooldrain];
/*
*通过[autoreleasePool drain];
*autorelease对象被一起release
*/
}
NSArray * arr1 = [NSArrayarray];//里面已经存在autorelease
NSArray * arr2 = [[[NSArrayalloc]init]autorelease];
NSMutableArray * mutableArr1 = [NSMutableArrayarrayWithCapacity:2];
NSMutableArray *mutableArr2 = [[[NSMutableArrayalloc]initWithCapacity:2]autorelease];
其实autorelease的实现,我们可以追溯到源代码
id obj = [[NSObjectalloc]init];
[obj autorelease];
其实obj内部实现应该是如下方式-(void)autorelease
{
[NSAutoreleasePooladdObject:self];
}
autorelease的实质方法的本质就是调用了 NSAutoreleasePool对象的 addObject的类方法
那到底苹果自己是如何处理NSAutoreleasePool的呢?它的内部实现应该是怎么样的呢,我们可以简单的如下猜想
NSAutoreleasePool调用的addObject方法如下:
+(void)addObject:(id)anObject
{
NSAutoreleasePool * autoreleasePool =//取得正在使用NSAutoreleasePool的对象;
if (autoreleasePool) {
[autoreleasePool addObject:anObject];
}else{
//对象非存在状态下调用autorelease
}
}
然后是 NSAutoreleasePool 的对象autoreleasePool调用 addObject:方法,此时被autorelease的该对象,将会被添加到正在使用的NSAutoreleasePool里面。那NSAutoreleasePool的对象能不能autorelease呢?
答案是不能的,如果你调用
[autoreleasePoolautorelease];就会出现异常
控制台你会看到
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSAutoreleasePool autorelease]: Cannot autorelease an autorelease pool'