揭开ARC的神秘面纱系列-第1话
这个系列一共有四篇博客,是Matt Galloway大神关于ARC的内部实现的一些探索,看完之后觉得收获不少。因此尝试着翻译出来和大家分享,一定会翻译不当之处,希望大家及时指正。
原文地址
以下是正文:
在Twitter上和@jacobrelkin进行了一次交流之后,我决定写几篇博客关于ARC在神秘的面纱之下是如何运转和如何窥视其内部机制的方法。这篇博客我将解释ARC如何处理retain、release和autorelease这三个关键字对应的内部实现。
我们通过定义一个类作为开始,如下:
1 |
|
1 |
|
继续向前,看看在ARC模式下又是怎样的一副景象。采用如下所示的指令进行编译:
$ /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk -arch armv7 -fobjc-arc -O3 -S -o - test-arc.m
同样,此刻我们只关注changeFooDirect:和changeFooDirect:这两个函数:
1 |
|
我们可以一目了然地看到两段汇编代码的不同之处。函数changeFooSetter:完全一样,而函数changeFooDirect:已经发生了变化:调用了一次objc_storeStrong函数。有意思的地方就是这里。如果我们查阅LLVM文档中objc_storeStrong函数的说明将会看到objc_storeStrong函数里完成一个典型的变量交换,释放旧变量然后持有新变量。然而在非ARC模式下,这个变量仅仅是赋值,并没有任何释放或者持有操作。这就是我们期望的结果,感谢ARC!
接下来是更有趣的地方,newNumber函数对比getNumber函数。这两个函数在非ARC模式下都返回一个引用计数为1的NSNumber对象,也就是说函数调用者持有返回对象。根据Cocoa的命名约定,这个结果似乎符合函数newNumber而不符合函数getNumber。我们期望看到函数getNumber中有调用autorelease。因此,让我们查看非ARC模式下的代码是怎样的:
1 |
|
然后是ARC模式下:
1 |
|
查看上述两段代码唯一不同点:ARC模式下getNumber:函数中调用了objc_autorelease。这也是我们所期望的,因为ARC模式能自动觉察到函数名是以关键字new还是关键字copy开头的,并为不属于这两种的情况的Get类函数的返回对象自动添加一次autorelease调用。棒极了!
这里仅仅只展示了关于ARC在两种模式下如何工作的一小部分奥秘,与此同时,我希望这能激励读者能自己去探索ARC的内部实现而不是理所当然的接受现有的知识点。作为一个程序员,理解自己使用的工具的内部实现是很重要的。