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

Objective-C 記憶體管理全景:從 MRC 到 ARC 的演進與實戰精要

     編輯:關於C語言

一、核心模型:引用計數

OC 物件配置於堆區,生命週期由引用計數控制:

  • 增 1:alloc / new / copy / mutableCopy / retain / strong 持有。
  • 減 1:release / autorelease(延遲釋放) / weak 參考不增加計數。
  • 計數歸零 → 自動呼叫 dealloc 釋放記憶體。

指標賦值 ≠ 計數增加

// MRC 手動管理範例
ClassA *obj1 = [[ClassA alloc] init]; // count=1
ClassA *obj2 = obj1;                  // count=1,僅複製指標
[obj2 retain];                        // count=2
[obj1 release];                       // count=1,物件存活
[obj2 release];                       // count=0 → dealloc

鐵律:release 後立即設為 nil,避免野指標;對 nil 發送訊息安全無害。

二、Autorelease Pool:延遲釋放機制

NSAutoreleasePool 內部維護一個陣列,收集 autorelease 物件;Pool 銷毀時遍歷發送 release。

// 傳統 MRC 寫法
- (NSString *)fullName {
    NSString *str = [[[NSString alloc] initWithFormat:@"%@ %@", first, last] autorelease];
    return str; // 呼叫端不持有,由 pool 稍後釋放
}

// 現代便利建構器等價寫法
- (NSString *)fullName {
    return [NSString stringWithFormat:@"%@ %@", first, last]; // 內部已 autorelease
}

巢狀 Pool 優化記憶體峰值

@autoreleasepool { // 外層 pool
    for (int i=0; i<100; i++) {
        @autoreleasepool { // 內層 pool,每輪釋放臨時物件
            for (int j=0; j<10000; j++) {
                [NSString stringWithFormat:@"%d", j];
            }
        }
    }
}

三、@property 關鍵字深度解析

關鍵字語意適用場景
assign單純指標賦值,不影響計數基本型別、非 OC 物件、delegate 弱參考(MRC)
copy內容複製,新物件 count=1NSString、NSArray、block 等不可變/需獨佔副本
retain指標複製 + count+1(MRC)MRC 環境下物件屬性
strong強參考,ARC 管理計數ARC 環境下物件擁有關係
weak弱參考,不增加計數,物件釋放自動置 nil打破循環保留、delegate、block 捕獲 self
unsafe_unretained弱參考但不自動置 nil(危險)極少用,需極度確定生命週期
atomic/nonatomic存取執行緒安全性(預設 atomic)多執行緒環境 atomic;高效能單執行緒 nonatomic
readonly/readwrite存取權限控制介面設計

Block 循環保留與 __weak 破解

__weak typeof(self) weakSelf = self;
self.completionBlock = ^{
    [weakSelf doSomething]; // weakSelf 可能為 nil,需在 block 內強參考
    // 或
    typeof(self) strongSelf = weakSelf;
    if (strongSelf) { [strongSelf doSomething]; }
};

四、ARC 自動引用計數:編譯器插桩規則

  • 編譯期自動插入 retain/release/autorelease,開發者不再手動呼叫。
  • strong 變數離開作用域自動 release;weak 變數物件釋放自動置 nil。
  • Core Foundation 物件需手動 CFRetain/CFRelease 或使用 __bridge 轉換所有權。

五、常見陷阱與避坑指南

  1. 集合類別持有元素:NSArray/NSDictionary 會 retain 加入的物件,移除時 release。
  2. Block 複製:Block 建立於堆疊,需 copy 至堆區才能安全跨作用域使用(ARC 下屬性宣告 copy 自動處理)。
  3. Delegate 循環:親持有子,子弱參考親;@property (weak) id delegate;。
  4. 單例模式:ARC 下 sharedInstance 靜態變數持有,永不釋放,符合預期。

六、總結

記憶體管理的本質是「誰負責釋放」。MRC 靠開發者嚴守規範,ARC 靠編譯器靜態分析插桩。理解引用計數、自動釋放池、屬性修飾語、循環保留四大支柱,即能駕馭各種複雜場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved