當對象被加入 NSMutableArray 時,數組會自動對其發送 retain 消息,增加引用計數;數組銷毀或移除元素時,發送 release。
Dog *dog1 = [[Dog alloc] init]; // 計數 = 1 Dog *dog2 = [[Dog alloc] init]; // 計數 = 1 NSMutableArray *array = [[NSMutableArray alloc] init]; [array addObject:dog1]; // dog1 計數 = 2 [array addObject:dog2]; // dog2 計數 = 2 [dog1 release]; // dog1 計數 = 1 [dog2 release]; // dog2 計數 = 1 [array release]; // 數組銷毀,內部對所有元素 release → dog1, dog2 計數歸 0,被銷毀 // 或移除所有元素 [array removeAllObjects]; // 等同於對每個元素 release
核心規則:集合類對象擁有其元素的「所有權」,生命週期綁定。
自動釋放池(NSAutoreleasePool / @autoreleasepool)延遲 release 操作,便於臨時對象管理。
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; Dog *dog = [[Dog alloc] init]; // 計數 = 1 [dog autorelease]; // 標記延遲 release NSLog(@"dog retainCount: %ld", dog.retainCount); // 仍為 1 [pool release]; // 池銷毀時,對池中所有對象發送 release → dog 計數歸 0,銷毀
NSAutoreleasePool *pool1 = [[NSAutoreleasePool alloc] init]; Dog *dog1 = [[Dog alloc] init]; [dog1 autorelease]; // 屬於 pool1 NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init]; Dog *dog2 = [[Dog alloc] init]; [dog2 autorelease]; // 屬於 pool2 [pool2 release]; // 先銷毀 pool2 → dog2 釋放 [pool1 release]; // 再銷毀 pool1 → dog1 釋放
嵌套池允許精細控制不同代碼塊中臨時對象的釋放時機,解決 @autoreleasepool {} 作用域限制導致的變量不可訪問問題。
@autoreleasepool { ... } ≡ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; ... [pool release];[pool release] 觸發池中所有對象的 release。掌握集合類的擁有權語義與自動釋放池的嵌套機制,是編寫無洩漏、無過度釋放 Objective-C 代碼的關鍵。手動管理池比系統隱式池更靈活,適合長時間運行或內存敏感場景。