autorelease是蘋果引以為傲的地方,它為程式開發人員減輕了很大的開發壓力,下面就介紹下autorelease。
autorelease ,顧名思義,就是自動釋放,它看上去就像是ARC,其實他更像C語言裡面的自動變量(局部變量),
C語言裡面的局部變量,就是當變量超出其作用域以後,該自動變量就會被自動抛棄。下面複習下C語言裡面的自動變量
-(void)getIt
{
int a =0;
}
audiorelease會像C語言裡面對待自動變量那樣,對待執行個體對象,當超出其作用域的時候,對象執行個體的release方法就會被調用,同自動變量不同的是,對象的作用域可以右程式開發人員自己設定。
autorelease的具體使用方法是:1)、生成并持有NSAutoReseasePool對象。2)、調用已配置設定對象的autorelease執行個體方法。3)、廢棄NSAutoReseasePool對象
-(void)objcAutorelease
{
NSAutoreleasePool * autoreleasePool = [[NSAutoreleasePoolalloc]init];
id objc = [[NSObjectalloc]init];
[objcautorelease];
[autoreleasePooldrain];
}
其實需要注意的是,如果大量對象autorelease,隻要NSAutoreleasePool沒有被廢棄,那麼生成的對象就不能被釋放,就會導緻記憶體不足,典型的例子是讀入大量的圖檔,并且改變圖檔的尺寸,圖像檔案讀入到NSData對象,并從中生成UIImage對象,這種情況會産生大量的autorelease對象,
for (int i =0; i<10000; i++) {
}
是以可以看出上面的理智是有問題的,是以我們需要在适當的位置,生成、持有、廢棄NSAutoreleasePool對象
for (int i =0; i<10000; i++) {
NSAutoreleasePool * autoreleasePool = [[NSAutoreleasePoolalloc]init];
[autoreleasePooldrain];
}
其實在cocoa中,有很多類方法傳回autorelease對象,比如說
NSArray * arr1 = [NSArrayarray];//裡面已經存在autorelease
NSArray * arr2 = [[[NSArrayalloc]init]autorelease];
NSMutableArray * mutableArr1 = [NSMutableArrayarrayWithCapacity:2];
NSMutableArray *mutableArr2 = [[[NSMutableArrayalloc]initWithCapacity:2]autorelease];
arr1 和arr2 mutableArr1和mutableArr1都是一個道理。
其實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'