本文为「iOS 内存管理」专题的总纲:说明内存管理的目标与约束、历史演进(MRC → ARC)、知识体系结构图,以及与其他分篇的衔接。细节见 00-索引 与各分篇。
一、为什么需要内存管理
1.1 目标与约束
- 目标:在有限的进程内存与系统约束下,让对象在需要时存活、在不再需要时及时释放,避免泄漏(占用不释放)与野指针(释放后仍被访问)。
- 约束:iOS 进程受系统限制,堆栈大小、堆可用空间有限;不当管理会导致 OOM、崩溃或卡顿。
1.2 谁在管理
| 区域 | 管理者 | 说明 |
|---|
| 栈 | 编译器/系统 | 局部变量、参数等自动入栈出栈,无需业务关心 |
| 堆 | 开发者(或 ARC) | 通过 引用计数 决定对象何时释放;历史上为 MRC,现多为 ARC |
本专题重点为堆上对象的引用计数与生命周期管理。其中 MRC、ARC 与 自动释放池 是三个核心概念,简介如下。
1.3 MRC、ARC、自动释放池 简介
| 概念 | 定义 | 要点 |
|---|
| MRC(Manual Reference Counting) | 开发者手动调用 retain / release / autorelease 管理对象引用计数的方式。 | 配对原则:谁 +1 谁 -1;alloc/new/copy 等返回的对象需在适当时机 release 或 autorelease。 |
| ARC(Automatic Reference Counting) | 编译器在编译期根据所有权(strong/weak 等)自动插入 retain/release/autorelease,开发者不手写。 | 底层仍是引用计数;需理解 strong/weak 与循环引用,Swift 仅支持 ARC。 |
| 自动释放池(AutoreleasePool) | 接收 autorelease 对象,在某一时刻(池 pop/drain)统一对池内对象发送 release,实现延迟释放。 | 主线程由 RunLoop 每轮 push/pop;可显式 @autoreleasepool { } 控制释放时机;MRC 与 ARC 共用同一套池。 |
关系示意:
flowchart LR
subgraph 引用计数
A[MRC 手写]
B[ARC 编译期插入]
end
subgraph 延迟释放
C[autorelease]
D[自动释放池]
end
A --> C
B --> C
C --> D
D --> E[池 pop 时 release]
二、历史演进
2.1 时间线概览
timeline
title iOS 内存管理演进
section 早期
NeXTStep / Objective-C : 引用计数 retain/release
iOS 2.x ~ 4.x : MRC 为主 开发者手动管理
section 自动化
WWDC 2011 / iOS 5 : 引入 ARC 编译期自动插入
Xcode 4.2+ : 支持 ARC 与 MRC 混编
section 当前
iOS 5+ / 现代工程 : ARC 成为默认与推荐
Swift : 仅支持 ARC 无 MRC
2.2 阶段说明
| 阶段 | 特点 |
|---|
| MRC(Manual Reference Counting) | 开发者显式调用 retain / release / autorelease;遵循「谁申请谁释放」「配对原则」;易出错(多 release、少 release、循环引用)。 |
| ARC(Automatic Reference Counting) | 编译器在编译期插入引用计数操作,开发者不再手写 retain/release;仍基于引用计数,需理解 strong/weak 与循环引用。 |
| Swift | 仅支持 ARC;strong / weak / unowned 与闭包捕获规则与 OC 类似,语法不同。 |
详见 03-引用计数与MRC详解、04-ARC详解。
三、知识体系结构(思维导图)
mindmap
root((内存管理总纲))
内存布局
五大分区
内存对齐 与 结构体布局
引用计数
加一 retain copy 等
减一 release autorelease
MRC
配对原则
所有权约定
ARC
编译期插入
strong weak unowned
自动释放池
@autoreleasepool
RunLoop 协作
弱引用与循环
weak 实现
循环引用 破除
四、MRC / ARC / 自动释放池 分篇指引
| 主题 | 分篇 | 内容侧重 |
|---|
| MRC | [03-引用计数与MRC详解](03-主题 | 内存管理@iOS-引用计数与MRC详解.md) | 引用计数原理、retain/release/autorelease 语义、配对原则、所有权命名约定、伪代码 |
| ARC | [04-ARC详解](04-主题 | 内存管理@iOS-ARC详解.md) | ARC 机制、strong/weak/unowned、与 MRC 对比、block 与循环引用、Swift ARC |
| 自动释放池 | [05-AutoreleasePool与RunLoop](05-主题 | 内存管理@iOS-AutoreleasePool与RunLoop.md) | @autoreleasepool、Push/Pop、AutoreleasePoolPage、与 RunLoop 协作、释放时机与应用场景 |
五、与其他分篇的关系
| 分篇 | 与本总纲的关系 |
|---|
| [01-内存五大分区](01-主题 | 内存管理@iOS-内存五大分区.md) | 建立「堆/栈/全局/常量/代码」的布局与地址认知,堆对象由引用计数管理 |
| [08-内存对齐](08-主题 | 内存管理@iOS-内存对齐.md) | 数据在内存中的对齐规则、结构体 padding、与五大分区中布局的关系 |
| [03-引用计数与MRC](03-主题 | 内存管理@iOS-引用计数与MRC详解.md) | 引用计数原理与 MRC 规则,是 ARC 的前置基础 |
| [04-ARC](04-主题 | 内存管理@iOS-ARC详解.md) | ARC 如何自动插入、所有权修饰符、与 MRC 对比 |
| [05-AutoreleasePool与RunLoop](05-主题 | 内存管理@iOS-AutoreleasePool与RunLoop.md) | 延迟释放与 RunLoop 的协作,理解「何时批量 release」 |
| [06-weak与循环引用](06-主题 | 内存管理@iOS-weak与循环引用.md) | weak 实现与循环引用破除,NSProxy 与 Timer 管理,避免泄漏与野指针 |
| [07-实践与常见问题](07-主题 | 内存管理@iOS-实践与常见问题.md) | 内存警告、内存泄漏分析、Timer 管理、音视频与图层场景、泄漏排查与最佳实践 |
| [09-Category与关联对象内存管理](09-主题 | 内存管理@iOS-Category与关联对象内存管理.md) | Category 不增加实例大小;关联对象 policy(RETAIN/COPY/ASSIGN)、释放时机与循环引用注意 |
| [10-Block内存管理](10-主题 | 内存管理@iOS-Block内存管理.md) | Block 三种类型(全局/栈/堆)、捕获与 copy、MRC/ARC 下 copy 规则、循环引用与 weak self |
| [11-深浅拷贝与内存](11-主题 | 内存管理@iOS-深浅拷贝与内存.md) | 浅拷贝与深拷贝、Foundation copy/mutableCopy、NSCopying、属性 copy 与内存、Swift 值类型与写时拷贝 |
| [12-Option与内存优化技术](12-主题 | 内存管理@iOS-Option与内存优化技术.md) | Option 位运算共用内存、内存极限管理、Copy-on-Write、Tagged Pointer |
六、参考文献