1.iOS内存管理有三种方法:ARC、MRC、内存池。
2.MRC:遵循谁申请、谁添加、谁释放的原则。需要手动处理内存技术的增加和修改。从12年iOS开始开始,逐步被ARC(自动内存计数)模式取代。
3.ARC就是取代了MRC,在App编译阶段,由Xcode添加了内存管理的代码。
4.内存释放池Release Pool:把需要释放的内存统一放在一个池子中,当池子被抽干后(drain),池子中所有的内存空间也被自动释放掉。 内存池的释放操作分为自动和手动。自动释放受runloop机制影响。
5.内存池是属于MRC的技术吗?ARC模式下有自动内存计数了,MRC下有手动内存处理了。那么内存池是MRC下的相对于release 方法的另一种内存计数处理方法吗?
6.我是搞不清ARC、MRC、内存池 三者的关系。
7.ARC的语义就是在实际开发中,根本不用操心内存管理问题。(是吗?)
ARC
和MRC
其实都是原始的内存管理方式,申请:alloc
;释放:release
,这种方式下内存的申请和释放都需要精确计算,对于比较复杂的程序,计算申请对象应该何时被释放是有些头昏脑热的事情。于是就出现了引用计数Reference Counting
这种方式,用来统计对象的使用情况以得到对象应不应该被释放。MRC
就是Mannul Reference Counting
,它需要手动进行对象使用的计算,也就是每次使用对象时,要手动的retain
一下给引用计数加一,而不再使用时还要release
一下给引用计数减一。这样写久了,会感觉特别麻烦,要费老大劲去写retain
和release
,于是乎就有了ARC
自动引用计数,原理也很简单,就是通过程序去推断retain
和release
应该出现的位置,代替我们去写retain
和release
。而
AutoRelease
则又是完全不同的一套思路,有点儿像Java
中的GC
垃圾清理机制,它不会像ARC
或者MRC
那样在对象不再会被使用时马上被释放,而是等到一个时机去释放它。在ARC
比较成熟的今天,用到的机会已经不多了,不过再一些特殊的场景下,AutoRelease
还是能达到ARC
所不能达到的效果的。你自己解释的很清楚了,ARC不能说完全不用考虑内存管理,但是做的确实很完善。内存池就是你存放你申请内存的地方,这个很好理解。我记得ARC的情况下,好像是把以前需要手动释放的内存直接放到release pool里就可以了,系统会自动释放掉release pool里的内存。MRC就是你说的那样,谁申请谁释放的原则。说起来还是喜欢MRC,有种大权在握的感觉。
如果要谈历史的话oc从面世时就是MRC的,而AutoRelease是2.0的特性。但是我不知道autorelease中还关系到runloop,我知道main函数中有用到runloop,能否解决一下?
MRC 最早,程序员手动管理内存。
ARC 的前身是 “Clang static analyzer” 项目,该项目用于分析 Objective-C 代码,找出内存泄漏、过早释放之类的错误,效果非常好以至于苹果考虑干脆用这个分析器来自动插入所有的 retain、release 算了,最终促成了 ARC 的产生。
自动释放池(Autorelease Pool)应该是和 MRC 同期的东西,和 ARC 没什么关系。常见使用场景是:某方法需要返回一个新创建的对象,但不想 retain 它,又担心提前释放问题,就发送 autorelease 消息,让自动释放池成为它的临时拥有者,不至于被提前释放,drain 时这个临时的计数也减掉了。
所以自动释放池的名字可能有点误导,自动释放池并不会“自动” release 任何东西,它 release 的都是你此前告诉它要 release 的。
总结一下:MRC 是程序员自己写 retain 、 release 来管理内存,自动释放池机制用于解决一些棘手的对象归属权问题, ARC 拯救万民于水火。
ARC 的执行结果就是自动加入了 retain 、 release 后的代码,和你 MRC 写的没什么两样,只是不容易出错。也就是说 ARC 的机制和 Java 的垃圾回收之类的完全不同, ARC 是编译时的机制,而不是运行时。
使用 ARC 依然需要关注内存问题,比如使用 block 时很容易出现的循环强引用,这类问题 ARC 是帮不了你的,比较基本,找本 Objective-C 的书应该都会讲。