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

Objective-C 基礎筆記(三):手動引用計數內存管理與自動釋放池機制

     編輯:關於C語言

Objective-C MRC 內存管理全景

在 ARC (自動引用計數) 普及前,MRC (手動引用計數) 是 Objective-C 內存管理的基石。理解 MRC 對維護舊代碼、調試 ARC 底層問題、跨語言橋接 (如 Objective-C++) 至關重要。

核心規則

  1. 擁有權:你創建 (alloc/new/copy/mutableCopy) 的對象,你擁有 (引用計數 +1),你負責釋放 (release/autorelease)。
  2. 非創建獲取:其他方式獲取的對象 (如工廠方法、屬性 getter) 通常**不擁有**,若需長期持有必須 retain (+1)。
  3. 平衡:每個 retain/alloc/copy 必須配對一個 release/autorelease。
  4. 銷毀:引用計數歸 0 時,運行時發送 dealloc,**切勿直接調用**,重寫 dealloc 釋放持有的資源並調用 [super dealloc]。

實戰代碼模式

// Book.h
@interface Book : NSObject
@property (nonatomic, assign) float price; // 基本類型用 assign
- (id)initWithPrice:(float)price;
@end

// Book.m
@implementation Book
@synthesize price = _price;
- (id)initWithPrice:(float)price {
    if (self = [super init]) _price = price;
    NSLog(@"買入: %.2f", _price);
    return self;
}
- (void)dealloc {
    NSLog(@"釋放: %.2f", _price);
    [super dealloc]; // 必須最後調用
}
@end

// Student.h
@interface Student : NSObject
@property (nonatomic, assign) int age;
@property (nonatomic, retain) Book *book; // 對象屬性用 retain
- (void)setBook:(Book*)book;
- (id)initWithAge:(int)age;
@end

// Student.m
@implementation Student
@synthesize age = _age, book = _book;
- (void)setBook:(Book*)book {
    if (_book != book) {
        [_book release]; // 釋放舊值
        [book retain];   // 保留新值
        _book = book;
    }
}
- (id)initWithAge:(int)age {
    if (self = [super init]) _age = age;
    return self;
}
- (void)dealloc {
    [_book release]; // 釋放持有對象
    [super dealloc];
}
@end

@class 前向聲明

頭文件中僅聲明指針類型屬性/參數時,用 @class Book; 替代 #import "Book.h",減少編譯依賴、避免循環引用。實現文件中再 #import。

@property 參數詳解

@property (nonatomic, retain) Book *book;
// nonatomic: 非原子操作,無鎖,性能高 (默認 atomic 加鎖)
// retain: setter 釋放舊值、retain 新值 (對象類型)
// copy: setter 釋放舊值、copy 新值 (NSString/NSArray/Block 常用)
// assign: 直接賦值 (基本類型、非對象指針、weak 代理)
@property (nonatomic, assign, getter=isEnabled) BOOL enabled; // 自定義 getter 名

自動釋放池

機制:對象發送 autorelease → 加入**當前線程最內層池** → 池排出時發送 release。延遲釋放,適合臨時對象。

// 三種寫法
@autoreleasepool { // 推薦:塊語法,作用域清晰
    id obj = [[[MyClass alloc] init] autorelease]; // 1. alloc/init/autorelease 鏈式
    id obj2 = [[MyClass alloc] init]; [obj2 autorelease]; // 2. 分步
    id obj3 = [MyClass create]; // 3. 類工廠方法內部 autorelease (慣例)
} // 池排出,obj/obj2/obj3 各 release 一次

// 嵌套池:內層池先排出
@autoreleasepool {
    @autoreleasepool { /* 內層臨時對象 */ }
    /* 外層長期對象 */
}

便利構造器模式

+ (id)student { // 類方法
    return [[[Student alloc] init] autorelease]; // 返回自動釋放對象
}
+ (id)studentWithAge:(int)age {
    Student *s = [Student student];
    s.age = age;
    return s;
}
// 使用:Student *s = [Student studentWithAge:20]; // 無需手動 release

MRC → ARC 遷移核心變化

MRCARC說明
retain/release/autorelease編譯器自動插入禁止手動調用
dealloc 釋放 ivar自動釋放 strong ivar僅需釋放非對象資源 (文件句柄、C 內存)
assign (對象)weak / unsafe_unretainedweak 自動置 nil,安全
@property (retain)@property (strong)語義同義
循環引用用 weak 打破MRC 用 assign 手動管理

雖然 ARC 已成主流,但 MRC 思想貫穿 Objective-C 運行時設計,深入掌握能讓你在疑難雜症面前游刃有餘。

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