是否可以在编译时看到ARC生成的代码?

Sak*_*res 14 xcode objective-c automatic-ref-counting

我已在"摘要"部分阅读过渡到ARC发行说明.他们告诉:

ARC的工作原理是在编译时添加代码,以确保对象在必要时生效,但不再生效.从概念上讲,它通过为您添加适当的内存管理调用,遵循与手动引用计数(在高级内存管理编程指南中描述)相同的内存管理约定.

为了让编译器生成正确的代码

我想知道ARC纠正我们代码的结果.

我的问题:我们能看到变化吗?(在分配,保留,分配或释放的期限.不是组装级别!)

原因:因为我认为在没有ARC模式的情况下,在旧的传统开发中看到最佳实践代码是很好的.

ken*_*ytm 26

通过将代码从ObjC重写为ObjC,但在代码生成期间发出额外的保留/释放LLVM bitcode,clang中的ARC不起作用.这意味着,无法在不进入LLVM IR /汇编级别的情况下知道编译器如何"修复"它.


如果ARC发出LLVM bitcode就像你说的那样.它的目的是在编译过程中使用更少的时间吗?(不太复杂的ObjC代码,更少的头文件?)

如果编译器可以减少通过代码的次数,那总是更好.


你能告诉我一些在汇编级别显示代码的示例或实用程序吗?

要获得汇编代码,您可以

  1. 直接从编译器生成程序集.在命令行中,-S在调用编译器时添加标志.结果是.S包含汇编代码的文件.在Xcode项目中,打开源代码文件,然后转到Product(在菜单栏上)→ Generate OutputAssembly File.

  2. 生成目标文件,然后反汇编它.内置命令otool -tvV <file>可以执行反汇编,并且有高级工具,如otx(免费)或IDA(免费评估).

我更喜欢路由2,因为它产生的垃圾更少,反汇编工具可以配置为产生更多有用的信息.无论如何,使用任何一种方法都需要能够读取汇编代码.

以此代码为例:

- (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;
}
Run Code Online (Sandbox Code Playgroud)

编译后,将生成以下程序集(使用IDA进行分析):

-[SomeAppDelegate application:didFinishLaunchingWithOptions:]:
    push       {r4-r7,lr}
    add        r7, sp, #0xC
    str.w      r8, [sp,-#0x4]!
    sub        sp, sp, #0x18
    movw       r1, #(0x343c - 0x2574)       ; @selector(alloc)
    mov        r8, r0
    movt.w     r1, #0
    mov        r0, (0x3464 - 0x2576)        ; _OBJC_CLASS_$_UIWindow
    add        r1, pc
    add        r0, pc
    ldr        r1, [r1]
    ldr        r0, [r0]
    blx        _objc_msgSend
    mov        r1, (0x3440 - 0x258e)        ; @selector(mainScreen)
    mov        r6, r0
    movw       r0, #(0x3468 - 0x2594)       ; _OBJC_CLASS_$_UIScreen
    add        r1, pc
    movt.w     r0, #0
    add        r0, pc
    ldr        r1, [r1]
    ldr        r0, [r0]
    blx        _objc_msgSend
    mov        r7, r7
    blx        _objc_retainAutoreleasedReturnValue
    mov        r5, r0
    cbz        r5, L25ba
    movw       r0, #(0x3444 - 0x25b2)       ; @selector(bounds)
    mov        r1, r5
    movt.w     r0, #0
    add        r0, pc
    ldr        r2, [r0]
    add        r0, sp, #0x8
    blx        _objc_msgSend_stret
    b          L25c4

L25ba:
    add        r0, sp, #0x8
    vmov.i32   q8, #0x80
    vstmia     r0, {d16-d17}

L25c4:
    mov        r1, (0x3448 - 0x25d2)        ; @selector(initWithFrame:)
    ldr        r0, [sp,#0x10]
    add        r1, pc
    ldr        r2, [sp,#0x8]
    ldr        r3, [sp,#0xc]
    ldr        r4, [sp,#0x14]
    stmea.w    sp, {r0,r4}
    mov        r0, r6
    ldr        r1, [r1]
    blx        _objc_msgSend
    mov        r4, r0
    mov        r0, (0x344c - 0x25F2)        ; @selector(setWindow:)
    mov        r2, r4
    add        r0, pc
    ldr        r1, [r0]
    mov        r0, r8
    blx        _objc_msgSend
    mov        r0, r4
    blx        _objc_release
    mov        r0, r5
    blx        _objc_release
    mov        r0, (0x3450 - 0x2610)        ; @selector(window)
    add        r0, pc
    ldr        r5, [r0]
    mov        r0, r8
    mov        r1, r5
    blx        _objc_msgSend
    mov        r7, r7
    blx        _objc_retainAutoreleasedReturnValue
    mov        r1, (0x3454 - 0x2630)        ; @selector(whiteColor)
    mov        r6, r0
    movw       r0, #(0x346C - 0x2636)       ; _OBJC_CLASS_$_UIColor
    add        r1, pc
    movt.w     r0, #0
    add        r0, pc
    ldr        r1, [r1]
    ldr        r0, [r0]
    blx        _objc_msgSend
    mov        r7, r7
    blx        _objc_retainAutoreleasedReturnValue
    mov        r4, r0
    mov        r0, (0x3458 - 0x2652)        ; @selector(setBackgroundColor:)
    mov        r2, r4
    add        r0, pc
    ldr        r1, [r0]
    mov        r0, r6
    blx        _objc_msgSend
    mov        r0, r4
    blx        _objc_release
    mov        r0, r6
    blx        _objc_release
    mov        r0, r8
    mov        r1, r5
    blx        _objc_msgSend
    mov        r7, r7
    blx        _objc_retainAutoreleasedReturnValue
    mov        r4, r0
    mov        r0, (0x345C - 0x2680)        ; @selector(makeKeyAndVisible)
    add        r0, pc
    ldr        r1, [r0]
    mov        r0, r4
    blx        _objc_msgSend
    mov        r0, r4
    blx        _objc_release
    movs       r0, #1
    add        sp, sp, #0x18
    ldr.w      r8, [sp], #4
    pop        {r4-r7,pc}

没有详细说明,你可以看到有很多_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;
Run Code Online (Sandbox Code Playgroud)

这与@c roald的链接描述的相同.