內(nèi)存管理篇: 3.autorelease
autorelease的實質(zhì):
將創(chuàng)建的對象加入到NSAutoreleasePool管理“數(shù)組”中,并告知ARC系統(tǒng)暫時不要對此對象進(jìn)行處理梅惯。待pool對象在其所屬的NSRunLoop循環(huán)一次完成盆繁,準(zhǔn)備釋放(drain)時卦羡,對“數(shù)組”中的所有對象依次調(diào)用release方法植捎。此時ARC再對對象進(jìn)行內(nèi)存管理芽狗。
GNUstep的實現(xiàn)
GNUstep的版本使用了同NSMutableArray一樣的連接列表鲤妥,將被標(biāo)記的對象加入到“正在使用中的”autoreleasePool對象中。
// NSObject.m中:
- (id)autorelease {
[NSAutoreleasePool addObject:self];
}
// NSAutoreleasePool.m中:
+ (void)addObject:(id)anObj {
NSAutoreleasePool *pool = 獲取正在使用中的pool夷恍;
if (pool != nil) {
[pool addObject:anObj];
} else {
...
}
}
- (void)addObject:(id)anObj {
// 加入到內(nèi)部管理的數(shù)組中
[array addObject:anObj];
}
方法調(diào)用優(yōu)化:在GNUstep實現(xiàn)的版本中魔眨,為了提高autorelease方法執(zhí)行的速度,使用了“IMP Caching”的方式酿雪,及將函數(shù)指針提前緩存遏暴,需要時跳過了“objc_msgSend”的過程,直接調(diào)用:
// NSObject.m中:
// 緩存類名
id autorelease_class = [NSAutoreleasePool class];
// 緩存方法名
SEL autorelease_sel = @selector("addObject:");
// 緩存方法實現(xiàn)(函數(shù)指針)
IMP autorelease_imp = [autorelease_class methodForSelector:autorelease_sel];
- (id)autorelease {
// 直接調(diào)用
(*autorelease_imp)(autorelease_class, autorelease_sel, self);
}
注意:
由于NSAutoreleasePool覆蓋了autorelease的方法實現(xiàn)(其他對象執(zhí)行的是NSObject的實現(xiàn))指黎,對pool對象發(fā)送autorelease消息會拋出異常朋凉。
即不能對NSAutoreleasePool對象調(diào)用autorelease方法。
- 補(bǔ)充:無論編譯環(huán)境是否為ARC有效醋安,都推薦使用@autoreleasepool塊作為替代杂彭,以提高代碼可讀性墓毒。