Objective-C 提供三種內存管理模式,現代開發以 ARC 為主,理解底層機制對調試洩漏、循環引用至關重要。
核心規則:你創建、你持有、你負責釋放。
alloc/new/copy/mutableCopy → 引用計數 +1,你擁有所有權retain → 顯式聲明持有,計數 +1release → 放棄持有,計數 -1;歸零時調用 deallocautorelease → 延遲釋放,加入當前自動釋放池判斷所有權:方法名以 alloc、new、copy、mutableCopy 開頭 → 返回對象歸調用者所有;否則(如 [NSString string]、[NSArray arrayWithObject:])返回自動釋放對象,調用者不持有,若需持有需手動 retain。
編譯器(Clang)在編譯期自動插入 retain/release/autorelease,開發者無需(也不可)手動調用。核心所有權修飾符:
| 修飾符 | 語義 | 適用場景 | |
|---|---|---|---|
__strong | 強引用(默認),持有所有權 | 普通對象屬性、局部變量 | |
__weak | 弱引用,不持有,對象銷毀自動置 nil | 打破循環引用(delegate、block 回調 self) | |
__unsafe_unretained | 弱引用,不置 nil(危險,懸空指針) | 極少用,兼容舊代碼 | |
__autoreleasing | 自動釋放池引用 | 雙指針輸出參數(NSError **) |
| 特性 | MRR | ARC | Garbage Collection (已棄用) |
|---|---|---|---|
| 機制 | 程序員手動管理 | 編譯器靜態插入 | 運行時掃描回收 |
| 性能 | 可預測,無額外開銷 | 編譯期優化,極低開銷 | 不可預測停頓,資源消耗大 |
| iOS 支持 | 早期版本 | iOS 5+ / OS X 10.7+ 全面支持 | 僅 Mac 64-bit,iOS 不支持 |
| 循環引用 | 手動打破 | __weak 自動打破 | 自動處理 |
__weak typeof(self) weakSelf = self; 在 block 內使用 weakSelf@property (weak) id delegate;CFRetain/CFRelease 或 __bridge 轉換