OC 物件配置於堆區,生命週期由引用計數控制:
alloc / new / copy / mutableCopy / retain / strong 持有。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 發送訊息安全無害。
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
}
@autoreleasepool { // 外層 pool
for (int i=0; i<100; i++) {
@autoreleasepool { // 內層 pool,每輪釋放臨時物件
for (int j=0; j<10000; j++) {
[NSString stringWithFormat:@"%d", j];
}
}
}
}
| 關鍵字 | 語意 | 適用場景 |
|---|---|---|
assign | 單純指標賦值,不影響計數 | 基本型別、非 OC 物件、delegate 弱參考(MRC) |
copy | 內容複製,新物件 count=1 | NSString、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 | 存取權限控制 | 介面設計 |
__weak 破解__weak typeof(self) weakSelf = self;
self.completionBlock = ^{
[weakSelf doSomething]; // weakSelf 可能為 nil,需在 block 內強參考
// 或
typeof(self) strongSelf = weakSelf;
if (strongSelf) { [strongSelf doSomething]; }
};
retain/release/autorelease,開發者不再手動呼叫。strong 變數離開作用域自動 release;weak 變數物件釋放自動置 nil。CFRetain/CFRelease 或使用 __bridge 轉換所有權。NSArray/NSDictionary 會 retain 加入的物件,移除時 release。copy 至堆區才能安全跨作用域使用(ARC 下屬性宣告 copy 自動處理)。@property (weak) id delegate;。sharedInstance 靜態變數持有,永不釋放,符合預期。記憶體管理的本質是「誰負責釋放」。MRC 靠開發者嚴守規範,ARC 靠編譯器靜態分析插桩。理解引用計數、自動釋放池、屬性修飾語、循環保留四大支柱,即能駕馭各種複雜場景。