首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Objective-C 記憶體管理核心規則:引用計數、所有權轉移與 ARC 時代的最佳實踐

     編輯:關於C語言

核心哲學:所有權模型

每個對象有一個引用計數器。擁有者負責在不再需要時釋放所有權。計數歸零 → 對象銷毀 (dealloc)。

MRR (手動引用計數) 四大鐵律

1. 你擁有你創建的對象

方法名以 alloc, new, copy, mutableCopy 開頭 → 返回對象擁有權歸調用者 (retainCount +1)。

MyClass *obj = [[MyClass alloc] init];      // 擁有
NSString *s = [NSString stringWithString:s]; // 擁有 (copy)

2. 通過 retain 獲取所有權

非創建方法獲取的對象 (如工廠方法、屬性 getter) 通常為自動釋放池管理。若需長期持有,必須 retain。

// 屬性設置器典型實現
- (void)setName:(NSString *)newName {
    if (_name != newName) {
        [newName retain];    // 獲取所有權
        [_name release];     // 釋放舊值所有權
        _name = newName;
    }
}

3. 不再需要時必須釋放所有權

  • release:立即減計數,歸零即銷毀
  • autorelease:延遲釋放,放入當前自動釋放池,池排空時發送 release
// 便利構造器模式
+ (instancetype)object {
    return [[[self alloc] init] autorelease]; // 移交所有權給池
}

4. 絕不釋放你不擁有的對象

過度 release → 過早銷毀 → 崩潰 (EXC_BAD_ACCESS)。靜態分析器 可捕獲大部分此類錯誤。

自動釋放池

  • 主線程 RunLoop 每次迭代創建/排空池
  • 子線程需手動 @autoreleasepool { ... }
  • 大量臨時對象循環中,內層建立池避免記憶體峰值

ARC (自動引用計數) 時代

編譯器自動插入 retain/release/autorelease。核心規則轉化為所有權修飾符:

修飾符語義MRR 等價
__strong (預設)持有強引用,擁有所有權retain 入,release 出
__weak非擁有引用,對象銷毀自動置 nil不 retain,不阻止銷毀
__unsafe_unretained非擁有引用,銷毀不置 nil (危險)僅賦值
__autoreleasing參數傳遞用,自動釋放池管理autorelease

常見循環引用與解決

  • 父子雙向引用:父 strong 子,子 weak 父
  • Block 捕獲 self:__weak typeof(self) weakSelf = self; 在 Block 內使用 weakSelf
  • 代理模式:@property (weak) id<Delegate> delegate;

最佳實踐清單

  1. 優先使用 ARC,新專案禁用 MRR
  2. 屬性預設 strong,代理/外部引用用 weak
  3. init/dealloc 中直接訪問實例變數 (_ivar),避免觸發 KVO/副作用
  4. 大循環內用 @autoreleasepool 釋放臨時對象
  5. 啟用 靜態分析器 (Cmd+Shift+B) 定期掃描
  6. Instruments → Leaks/Allocations 實測記憶體曲線
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved