00-主题|内存管理@iOS-索引

3 阅读8分钟

本专题围绕 iOS 内存管理 展开,从 Apple 官方文档、WWDC、技术博客与工程实践出发,系统介绍内存分区、引用计数、MRCARC自动释放池、weak 与循环引用、Category 与关联对象Block 内存管理深浅拷贝、以及实践与调优。同一主题按「总纲 → 内存分区 → … → Block 内存管理 → 深浅拷贝」拆成多篇,便于按需阅读与查阅。


一、核心概念简介:MRC、ARC、自动释放池

MRC(Manual Reference Counting,手动引用计数)

  • 是什么:由开发者手写 retainreleaseautorelease 来增减对象引用计数的内存管理方式;对象引用计数为 0 时被销毁。
  • 特点:遵循「谁让引用计数 +1,谁就要在合适时机 -1」的配对原则;灵活但易出错(漏 release 导致泄漏、多 release 或误用已释放对象导致野指针)。
  • 何时用:iOS 5 之前为主流;当前新工程普遍用 ARC,仅少数遗留或特殊场景仍开 MRC。
  • 详见03-引用计数与MRC详解

ARC(Automatic Reference Counting,自动引用计数)

  • 是什么编译器在编译期根据代码与所有权修饰符,自动插入 retain/release/autorelease 等调用;底层仍是引用计数,只是不再手写。
  • 特点:开发者通过 strong / weak / unowned 等表达「谁持有对象」;仍需理解循环引用并用 weak 打破。
  • 何时用:iOS 5+ 起推荐,当前 Objective-C 与 Swift 新项目的默认方式;Swift 仅支持 ARC。
  • 详见04-ARC详解

自动释放池(AutoreleasePool)

  • 是什么:用于延迟释放的机制:对象调用 autorelease 后不立刻 -1,而是加入当前自动释放池,由池在某一时刻(如 RunLoop 迭代结束、或显式 @autoreleasepool {}}统一对池内对象发送 release。
  • 特点:主线程 RunLoop 每次循环会 push/pop 一次顶层池,因此主线程上 autorelease 对象多在「本次事件处理结束」时被批量释放;子线程若无 RunLoop 需显式 @autoreleasepool 控制释放时机。
  • 何时用:循环中大量创建临时对象、子线程中大量 autorelease 对象时,可用 @autoreleasepool { } 控制峰值与释放时机。
  • 详见05-AutoreleasePool与RunLoop

三者关系小结

概念与引用计数的关系与自动释放池的关系
MRC手写 retain/release,autorelease 将对象交给池需理解 autorelease 与池的 drain 时机
ARC编译器自动插入 retain/release,语义同 MRC编译器在需要时插入 autorelease,池的机制不变
自动释放池接收 autorelease 对象,在 pop 时对它们 release与 MRC/ARC 共用同一套池(RunLoop 或 @autoreleasepool)

Category 与关联对象

  • 是什么Category 不能添加实例变量,若要在分类中「挂载」数据,需用运行时的 关联对象objc_setAssociatedObject / objc_getAssociatedObject)。关联的 value 的持有方式由 关联策略(policy) 决定:RETAIN/COPY 表示强引用或拷贝持有,ASSIGN 表示不持有(注意野指针与循环引用)。
  • 特点:主对象 dealloc 时,运行时会自动按 policy 释放所有关联的 value,一般无需在 dealloc 里手动移除。
  • 何时用:为系统类或已有类通过 Category 添加「存储型属性」、或为任意对象挂扩展数据时;需正确选择 policy 并避免循环引用。
  • 详见09-Category与关联对象内存管理

Block 内存管理

  • 是什么Block 是 OC 的闭包,可捕获变量、作为对象参与引用计数;在内存上分为 全局 Block(无捕获)、栈 Block(捕获自动变量)、堆 Block(copy 到堆),并会对捕获的 OC 对象产生强引用。
  • 特点:栈 Block 需 copy 到堆才能跨作用域安全使用(ARC 下多数场景自动 copy);Block 强引用 self 且 self 强引用 Block 会循环引用,需用 __weak self 打破。
  • 何时用:使用 Block/闭包作为属性、回调、异步任务时,需注意 copy 语义与循环引用;属性用 copy/strong,捕获 self 时用 weak。
  • 详见10-Block内存管理

深浅拷贝与内存

  • 是什么浅拷贝只复制当前层,得到新对象但内部元素仍指向原对象(引用计数 +1,共享子对象);深拷贝递归复制整棵对象树,拷贝与原对象完全独立,占用新内存。
  • 特点:Foundation 的 copy/mutableCopy 对集合多为浅拷贝(新容器、元素共享);属性 copy 在 setter 里对传入值做 copy,与 Block/NSString 常用;深拷贝需自定义或 initWithArray:copyItems:YES 等单层深拷贝。
  • 何时用:需要「多一份引用但可共享内容」用浅拷贝;需要「完全独立、避免被外部修改」用深拷贝,注意内存与性能。
  • 详见11-深浅拷贝与内存

Option 与内存优化技术

  • Option 位运算共用内存:用 NS_OPTIONS / 位域 / OptionSet 将多个布尔或选项压进一个整数,通过位运算读写,节省内存;适合 UI 状态、权限、配置等。
  • 内存极限管理:在低内存、后台等场景下通过缓存上限、didReceiveMemoryWarning、按需加载等控制占用。
  • Copy-on-Write(COW):值类型(如 Swift Array)在未修改前共享 buffer,写时才复制,兼顾值语义与内存/性能。
  • Tagged Pointer:64 位下将小对象(如小 NSNumber、短 NSString)编码进指针本身,无堆分配、无引用计数,极省内存与开销。
  • 详见12-Option与内存优化技术

二、专题知识全景(思维导图)

mindmap
  root((iOS 内存管理))
    内存分区
      栈 堆 全局 常量 代码
      地址与分配时机
    内存对齐
      结构体对齐 padding
      size 与 stride
    引用计数
      retain release
      MRC 配对原则
    ARC
      强引用 弱引用
      编译期插入
    自动释放池
      AutoreleasePoolPage
      RunLoop 与释放时机
    weak 与循环引用
      SideTable weak_table
      打破循环 NSProxy Timer
    实践
      内存警告 Instrument
      泄漏分析 音视频 图层
    Category 与关联对象
      关联策略 policy
      释放时机 循环引用
    Block 内存管理
      全局 栈 堆 Block
      捕获 copy 循环引用
    深浅拷贝
      浅拷贝 深拷贝
      引用计数 共享与独立
    Option 与内存优化
      Option 位运算 共用内存
      内存极限管理 COW Tagged Pointer

三、文档列表与阅读顺序

序号文档内容概要
00本文(索引)专题结构、知识全景、文档列表与阅读顺序
01[01-主题内存管理@iOS-内存五大分区](01-主题内存管理@iOS-内存五大分区.md)栈、堆、全局区、常量区、代码区的定义、地址特征、验证与栈帧
02[02-主题内存管理@iOS-总纲与知识体系](02-主题内存管理@iOS-总纲与知识体系.md)内存管理目标、历史演进(MRC→ARC)、知识体系图与选型指引
03[03-主题内存管理@iOS-引用计数与MRC详解](03-主题内存管理@iOS-引用计数与MRC详解.md)引用计数原理、MRC 规则、retain/release/autorelease、配对原则与伪代码
04[04-主题内存管理@iOS-ARC详解](04-主题内存管理@iOS-ARC详解.md)ARC 机制、strong/weak/unowned、所有权修饰符、与 MRC 的对比
05[05-主题内存管理@iOS-AutoreleasePool与RunLoop](05-主题内存管理@iOS-AutoreleasePool与RunLoop.md)自动释放池原理、AutoreleasePoolPage、与 RunLoop 的协作与释放时机
06[06-主题内存管理@iOS-weak与循环引用](06-主题内存管理@iOS-weak与循环引用.md)weak 实现、SideTable/weak_table、循环引用破除、NSProxy 与 Timer 管理、block 注意点
07[07-主题内存管理@iOS-实践与常见问题](07-主题内存管理@iOS-实践与常见问题.md)内存警告、内存泄漏分析(堆快照/VM/引用链)、Timer 管理、野指针、音视频与图层场景、最佳实践
08[08-主题内存管理@iOS-内存对齐](08-主题内存管理@iOS-内存对齐.md)内存对齐概念、结构体对齐规则与 padding、iOS/ARM64 约定、Swift MemoryLayout、与五大分区的关系
09[09-主题内存管理@iOS-Category与关联对象内存管理](09-主题内存管理@iOS-Category与关联对象内存管理.md)Category 与内存、关联对象 API、关联策略(RETAIN/COPY/ASSIGN)、释放时机、循环引用与最佳实践
10[10-主题内存管理@iOS-Block内存管理](10-主题内存管理@iOS-Block内存管理.md)Block 三种类型(全局/栈/堆)、捕获与引用、copy 语义、MRC/ARC 差异、循环引用与 weak self、Swift 闭包
11[11-主题内存管理@iOS-深浅拷贝与内存](11-主题内存管理@iOS-深浅拷贝与内存.md)浅拷贝与深拷贝定义、Foundation copy/mutableCopy、NSCopying、属性 copy、内存与选型、Swift 值类型与写时拷贝
12[12-主题内存管理@iOS-Option与内存优化技术](12-主题内存管理@iOS-Option与内存优化技术.md)Option 位运算共用内存(NS_OPTIONS/位域案例)、内存极限管理Copy-on-WriteTagged Pointer

建议阅读顺序:先读 02 总纲 建立演进与体系,再读 01 内存五大分区 理解布局;08 内存对齐 可与 01 配合理解数据在栈/堆中的布局;然后按 03 → 04 掌握引用计数与 ARC;05、06 深入自动释放池与 weak;07 做实践与排错;09 在需要为 Category 添加「属性」或使用关联对象时阅读,注意关联策略与循环引用;10 在使用 Block/闭包作为属性或回调时阅读,理解三种 Block 类型、copy 与循环引用;11 在需要区分容器/对象「共享」与「独立副本」、或实现自定义 copy 时阅读,理解深浅拷贝与内存关系;12 了解 Option 位运算共用内存内存极限管理Copy-on-WriteTagged Pointer 时阅读。


四、参考文献与权威来源