返回

从 Runtime 源码角度,深度解读 OC 对象的引用计数原理

IOS

在我们日常的 Objective-C 开发中,得益于 ARC 机制,我们无需再进行手动内存管理。但是,ARC 并非让我们免除了对内存管理的关心,它只是帮我们在合适的时间和地点对对象执行 -retain-release 操作,本质上仍然需要我们理解对象的引用计数机制。

要深入理解引用计数机制,我们不妨从 Runtime 源码的角度进行剖析,揭开 OC 对象引用计数原理的神秘面纱。

引用计数的基本原理

在 OC 中,每个对象都有一个引用计数,它是一个无符号 32 位整数,记录着该对象被引用的次数。当对象被创建时,它的引用计数初始化为 1。每当对象被强引用(比如赋值给一个局部变量),它的引用计数就会增加 1;每当强引用被解除时,它的引用计数就会减少 1。当对象的引用计数降为 0 时,对象会被自动释放。

Runtime 中的引用计数实现

在 Runtime 中,对象的引用计数存储在 objc_object 结构体中:

struct objc_object {
    Class isa;
    long retainCount;
    ...
};

retainCount 成员变量就是对象的引用计数。

引用计数操作的 Runtime 实现

在 Runtime 中,引用计数的操作主要通过以下几个函数实现:

  • objc_retain:增加对象的引用计数
  • objc_release:减少对象的引用计数
  • objc_retainAutorelease:增加对象的引用计数,并将其加入到自动释放池中
  • objc_autorelease:将对象加入到自动释放池中
  • objc_releaseAutoreleasePool:释放自动释放池中的所有对象

ARC 中的引用计数管理

在 ARC 下,编译器会自动在适当的地方插入引用计数操作。例如,当我们声明一个局部变量时,编译器会自动在变量声明处插入 objc_retain 操作;当变量作用域结束时,编译器会自动在变量声明处插入 objc_release 操作。

剖析 OC 对象引用计数原理

从 Runtime 源码的角度,我们可以剖析 OC 对象引用计数原理如下:

  1. 当一个 OC 对象被创建时,Runtime 会为其分配内存并初始化 retainCount 为 1。
  2. 当对象被强引用时,Runtime 会调用 objc_retain 函数,将 retainCount 加 1。
  3. 当强引用被解除时,Runtime 会调用 objc_release 函数,将 retainCount 减 1。
  4. 当对象的 retainCount 降为 0 时,Runtime 会释放该对象所占用的内存。

总结

通过对 Runtime 源码的分析,我们深入了解了 OC 对象引用计数原理。理解引用计数机制对于我们编写出内存安全、高效的 OC 代码至关重要。尽管 ARC 帮我们简化了内存管理,但我们仍然需要具备对引用计数机制的深刻理解,以避免潜在的内存问题。