之前接手公司的一个 iOS SDK 项目,是用 MRC
进行内存管理的。最终,我将这个项目迁移成了 ARC
。
苹果在 2011 年的时候,在 WWDC 大会上提出了自动的引用计数(ARC)。ARC 背后的原理是依赖编译器的静态分析能力,通过在编译时找出合理的插入引用计数管理代码,从而彻底解放程序员。
在 ARC 刚刚出来的时候,业界对此黑科技充满了怀疑和观望,加上现有的 MRC 代码要做迁移本来也需要额外的成本,所以 ARC 并没有被很快接受。直到 2013 年左右,苹果认为 ARC 技术足够成熟,直接将 macOS(当时叫 OS X)上的垃圾回收机制废弃,从而使得 ARC 迅速被接受。
2014 年的 WWDC 大会上,苹果推出了 Swift 语言,而该语言仍然使用 ARC 技术,作为其内存管理方式。
如今,使用 XCode 生成的项目,都是使用 ARC
作为内存管理的默认方法了。但是,我们仍需要了解,ARC
背后的原理。
一。什么是引用计数
引用计数(Reference Count)是一个简单而有效的管理对象生命周期的方式。当我们创建一个新对象的时候,它的引用计数为 1,当有一个新的指针指向这个对象时,我们将其引用计数加 1,当某个指针不再指向这个对象是,我们将其引用计数减 1,当对象的引用计数变为 0 时,说明这个对象不再被任何指针指向了,这个时候我们就可以将对象销毁,回收内存。由于引用计数简单有效,除了 Objective-C 和 Swift 语言外,微软的 COM(Component Object Model )、C++11(C++11 提供了基于引用计数的智能指针 share_prt)等语言也提供了基于引用计数的内存管理方式。
ARC
ARC 本质还是 MRC,只是 retain 和 release 的过程由编译器为你完成了,如果你写的不好,依然会内存泄漏,而学会 MRC 可以帮助你分析内存泄漏原因
混合使用 MRC、ARC
方法就是在 Build Phase 里面的 Compile Source 里面找到需要特殊处理的文件,加上编译选项 (Compiler Flags),具体针对上面两种情况有所区别。
- 旧项目没有使用 ARC,引入的第三方库使用了 ARC 的,给要添加的 ARC 源文件,添加 - fobjc-arc 选项
- 新项目使用了 ARC,引入的第三方库没有使用 ARC,给引入的第三方库添加 - fno-objc-arc