在clang中,ARC不是通过将ObjC代码重写为ObjC来实现的,而是在代码生成过程中发出了额外的retain/release LLVM位码。这意味着,如果不到达LLVM IR /汇编级别,就无法知道编译器如何"修复"它。
如果像你说的那样,ARC会发出LLVM位码。这是否是为了在编译过程中使用更少的时间?(更简单的ObjC代码,更少的头文件?)
如果编译器可以减少对代码的遍历次数,那肯定是更好的。
您能给我展示一些在汇编级别显示代码的示例或实用程序吗?
要获取汇编代码,您可以:
直接从编译器生成汇编。在命令行中调用编译器时,加入-S
标志。结果是包含汇编代码的.S
文件。在Xcode项目中,打开源代码文件,然后转到Product(菜单栏上)→Generate Output→Assembly File。
生成目标文件,然后对其进行反汇编。内置命令otool -tvV <file>
可执行反汇编,还有高级工具如otx(免费)或IDA(免费评估版)。
我更喜欢第二种方法,因为它生成的垃圾较少,反汇编工具可以配置为产生更有用的信息。无论哪种方法,您都需要能够阅读汇编代码。
以此代码为例:
- (BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
不详细解释,你可以看到有很多_objc_release
和_objc_retainAutoreleasedReturnValue
。 这些是ARC在代码生成期间插入的。手动反编译得到:
UIScreen* r5 = objc_retainAutoreleasedReturnValue([UIScreen mainScreen]);
CGRect sp8 = r5 != nil ? [r5 bounds] : CGRectZero;
UIWindow* r4 = [[UIWindow alloc] initWithFrame:sp8];
[self setWindow:r4];
objc_release(r4);
objc_release(r5);
UIWindow* r6a = objc_retainAutoreleasedReturnValue([self window])
UIColor* r4a = objc_retainAutoreleasedReturnValue([UIColor whiteColor])
[r6a setBackgroundColor:r4a];
objc_release(r4a);
objc_release(r6a);
UIWindow* r4b = objc_retainAutoreleasedReturnValue([self window])
[r4b makeKeyAndVisible];
objc_release(r4b);
return 1;
这与@c roald的链接描述的完全相同。