Autorelease Pool (自動釋放池) 是 Cocoa 記憶體管理機制之一:
autorelease 訊息後被加入池中。release,間接實現延遲釋放。
// ARC 環境 (iOS 5.0+ / OS X 10.7+)
@autoreleasepool {
// 池內代碼
id obj = [[MyClass alloc] init];
[obj autorelease]; // 手動加入 (ARC 下較少見)
} // 離開大括號自動銷毀池,發送 release
// 非 ARC 環境 (舊專案)
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// ... 代碼 ...
[pool drain]; // 或 [pool release] (ARC 下需用 drain)
@autoreleasepool {
Person *tom = [[Person alloc] init]; // retainCount = 1
[tom autorelease]; // 加入池,稍後 release
NSLog(@"pool exist"); // tom 仍存活
}
NSLog(@"pool dead"); // 池銷毀,tom 收到 release → dealloc
輸出順序:pool exist → Person dealloc → pool dead
@autoreleasepool {
Person *tom = [[Person alloc] init]; // 1
[tom autorelease]; // 池持有
[tom retain]; // 2 (手動持有)
NSLog(@"pool exist, retainCount=%ld", [tom retainCount]); // 2
[tom release]; // 1
NSLog(@"after release, retainCount=%ld", [tom retainCount]); // 1
}
NSLog(@"pool dead"); // 池釋放 → retainCount 歸 0 → dealloc
@autoreleasepool { // 外層池
Person *tom = [[Person alloc] init]; // 1
@autoreleasepool { // 內層池
[tom autorelease]; // 加入內層池
[tom retain]; // 2
NSLog(@"inner pool exist, retainCount=%ld", [tom retainCount]); // 2
}
NSLog(@"inner pool dead, retainCount=%ld", [tom retainCount]); // 1 (內層池釋放)
}
NSLog(@"outer pool dead"); // 外層池釋放 → dealloc
關鍵規則:autorelease 將物件加入當前最內層 (棧頂) 池。
| 取得方式 | 擁有權 | 釋放責任 |
|---|---|---|
alloc/new/copy/mutableCopy | 你擁有 | 你必須 release/autorelease |
| 其他方法 (工廠、便利建構子) | 你不擁有 | 自動釋放池負責 (單例除外) |
[pool release]:發送 release 給池內物件,並銷毀池本身 (非 ARC)。[pool drain]:僅發送 release 給池內物件,不銷毀池 (ARC 環境建議使用,等同於離開 @autoreleasepool 區塊)。@autoreleasepool,每輪釋放,避免記憶體尖峰。@autoreleasepool 仍可控制作用域。