ARC在编译期和运行期做了什么

Posted Billy Miracle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ARC在编译期和运行期做了什么相关的知识,希望对你有一定的参考价值。

除了会自动调用“保留”与“释放”方法外,使用ARC还有其他好处,它可以执行一些手工操作很难甚至无法完成的优化。
在编译期,ARC会把能够相互抵消的retainreleaseautorelease操作约简。如果发现在同一个对象上执行了多次“保留”与“释放”操作,那么ARC有时可以成对的移除这两个操作。ARC会分析对象的生存期需求,并在编译时自动插入适当的内存管理方法调用的代码,而不需要你记住何时使用retainreleaseautorelease方法。编译器还会为你生成合适的dealloc方法。
将内存管理交由编译器和运行期组件来做,可以使代码得到多种优化。比如,ARC可以在运行期检测到autorelease后面跟随retain这一对多余的操作。为了优化代码,在方法中返回自动释放的对象时,会执行一个特殊函数。

一些问答

  • 我应该如何看待 ARC ?它将 retains/releases 调用的代码放在哪了?

    尝试不要去思考ARC将retains/releases调用的代码放在哪里,而是思考应用程序算法,思考对象的strongweak指针、所有权、以及可能产生的循环引用。

  • 我还需要为我的对象编写 dealloc 方法吗?

    有时候需要。因为ARC不会自动处理malloc/free、Core Foundation对象的生命周期管理、文件描述符等等,所以你仍然可以通过编写dealloc方法来释放这些资源。你不必(实际上不能)释放实例变量,但可能需要对系统类和其他未使用ARC编写的代码调用[self setDelegate:nil]。ARC下的dealloc方法中不需要且不允许调用[super dealloc],Runtime会自动处理。

  • ARC 中仍然可能存在循环引用吗?

    是的,ARC自动retain/release,也继承了循环引用问题。幸运的是,迁移到ARC的代码很少开始泄漏,因为属性已经声明是否retain

  • block 是如何在 ARC 中工作的?

    在ARC下,编译器会根据情况自动将栈上的block复制到堆上,比如block作为函数返回值时,这样你就不必再调用Block Copy
    需要注意的一件事是,在ARC下,NSString * __block myString这样写的话,block会对NSString对象强引用,而不是造成悬垂指针问题。如果你要和MRC保持一致,请使用__block NSString * __unsafe_unretained myString或(更好的是)使用__block NSString * __weak myString

  • ARC 速度上慢吗?

    不。编译器有效地消除了许多无关的retain/release调用,并且已经投入了大量精力来加速 Objective-C 运行时。特别的是,当方法的调用者是ARC代码时,常见的 “return a retain/autoreleased object” 模式要快很多,并且实际上并不将对象放入自动释放池中。

以上是关于ARC在编译期和运行期做了什么的主要内容,如果未能解决你的问题,请参考以下文章

java编译期和运行期和string原理

ClassLoader Java中类加载出现在哪个阶段,编译期和运行期? 类加载和类装载是一样的吗

Java编译期和运行期 & JVM

八股文--反射http学习

深入java内存区域

深入理解java的反射机制