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

Objective-C 手動記憶體管理(MRC)核心規則與屬性修飾符完整指南

     編輯:關於C語言

MRC 三大核心方法

方法作用引用計數變化
retain聲明擁有權+1
release放棄擁有權-1
autorelease延遲釋放(下一個自動釋放池清空時)延遲 -1
copy創建副本(新對象)新對象計數 = 1

屬性修飾符對應的 Setter 語義

1. retain / strong(ARC 術語)

// MRC 手寫 setter 等價邏輯
- (void)setNames:(NSMutableArray *)names {
    if (_names != names) {
        [_names release];          // 1. 釋放舊值
        _names = [names retain];   // 2. 保留新值
    }
}
// dealloc 時需 [_names release] 平衡

2. assign / weak

- (void)setAge:(int)age {
    _age = age;  // 純賦值,無 retain/release
}
// 適用:基本數據類型、delegate 避免循環引用

3. copy

- (void)setNames:(NSMutableArray *)names {
    _names = [names copy];  // 創建不可變副本
}
// 必須用於:NSString、NSArray、NSDictionary 等不可變類
// 原因:防止外部修改可變對象導致內部狀態意外改變

4. readonly

  • 僅生成 getter,無 setter
  • 常用於初始化後不可變的屬性

5. nonatomic vs atomic

| 特性 | nonatomic | atomic | |------|-----------|--------| | 線程安全 | 否 | 是(鎖保護) | | 效能 | 高 | 低 | | 適用場景 | 單線程、內部數據、效能敏感 | 多線程共享數據 | | 預設值 | 否 | **是**(歷史原因) |

類型對應修飾符速查表

| 數據類型 | 推薦修飾符 | 理由 | |----------|------------|------| | 基本類型 (int, float, BOOL...) | `assign` / `weak` | 無引用計數,預設即可 | | **NSString** | **`copy`** | 防止可變副本修改鏈式反應 | | 其他不可變對象 (NSArray, NSDictionary...) | `copy` | 同上 | | 可變對象 (NSMutableArray...) | `strong` / `retain` | 通常需保持同一對象引用 | | Delegate / Block | `weak` | 避免循環引用 | | IBOutlet | `weak` (iOS) / `strong` (macOS) | 視圖層級所有權語義 |

記憶體管理黃金法則

  1. 誰創建,誰釋放:`alloc`/`new`/`copy`/`mutableCopy` → 你擁有 → 需 `release`/`autorelease`
  2. 取得非你創建的對象:若需長期持有 → `retain`;用完 → `release`
  3. Setter 規範:`retain`/`copy` 舊值 release → 新值 retain/copy
  4. Dealloc 清理:所有 `retain`/`copy` 持有的屬性逐一 `release`
  5. Autorelease 池:`@autoreleasepool { ... }` 限制作用域,避免臨時對象堆積

常見崩潰場景與修正

| 場景 | 錯誤代碼 | 修正 | |------|----------|------| | 過度釋放 | `[obj release]; [obj release];` | 僅釋放一次,或改用 `autorelease` | | 野指針訪問 | `release` 後繼續用 `obj` | `release` 後置 `nil`:`[obj release]; obj = nil;` | | 循環引用 | A.retain(B), B.retain(A) | 一邊用 `weak`/`assign`(通常 delegate/block) | | 可變對象外洩 | `@property (retain) NSMutableArray *arr;` | 改 `@property (copy) NSArray *arr;` 並內部用可變版本操作 |

從 MRC 遷移到 ARC 核心心智轉變

  • **不再手寫** `retain`/`release`/`autorelease`/`dealloc`(除非管理 Core Foundation/C++ 對象)
  • **屬性修飾符映射**:`retain` → `strong`,`assign` → `weak`/`unsafe_unretained`,`copy` 保持
  • **編譯器插入** 的釋放代碼基於所有權修飾符與作用域分析
  • **循環引用** 仍需開發者用 `weak` 斷開

總結

MRC 時代的記憶體管理雖繁瑣,但強迫開發者建立所有權、生命週期、引用計數的精確心智模型。理解這些本質,對於除錯 ARC 時代的循環引用、過早釋放、Core Foundation 橋接等疑難雜症依然至關重要。

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