首页 > 解决方案 > 为什么@objc 会生成保留和释放调用?

问题描述

我正在研究@objcSwift 中的注释如何影响生成的汇编代码。据我所知,这个注释生成了一个蹦床函数,它执行两个功能:

  1. self将参数从x0into移动x20以符合 Swift ABI
  2. 调用所有参数(分别在调用 Swift 代码之前和之后retainrelease

这是来自 iOS 应用程序的蹦床的汇编代码scene:WillConnectTo:options:,例如:

MyApp`@objc SceneDelegate.scene(_:willConnectTo:options:):
    0x102a850fc <+0>:   stp    x24, x23, [sp, #-0x40]!
    0x102a85100 <+4>:   stp    x22, x21, [sp, #0x10]
    0x102a85104 <+8>:   stp    x20, x19, [sp, #0x20]
    0x102a85108 <+12>:  stp    x29, x30, [sp, #0x30]
    0x102a8510c <+16>:  add    x29, sp, #0x30            ; =0x30 
    0x102a85110 <+20>:  mov    x19, x4
    0x102a85114 <+24>:  mov    x20, x3
    0x102a85118 <+28>:  mov    x21, x2
    0x102a8511c <+32>:  mov    x22, x0
    0x102a85120 <+36>:  bl     0x102a85640               ; symbol stub for: objc_retain
    0x102a85124 <+40>:  mov    x23, x0
    0x102a85128 <+44>:  mov    x0, x21
    0x102a8512c <+48>:  bl     0x102a85640               ; symbol stub for: objc_retain
    0x102a85130 <+52>:  mov    x21, x0
    0x102a85134 <+56>:  mov    x0, x20
    0x102a85138 <+60>:  bl     0x102a85640               ; symbol stub for: objc_retain
    0x102a8513c <+64>:  mov    x24, x0
    0x102a85140 <+68>:  mov    x0, x19
    0x102a85144 <+72>:  bl     0x102a85640               ; symbol stub for: objc_retain
    0x102a85148 <+76>:  mov    x19, x0
    0x102a8514c <+80>:  mov    x0, x21
    0x102a85150 <+84>:  mov    x20, x22
    0x102a85154 <+88>:  bl     0x102a853a4               ; function signature specialization <Arg[1] = Dead, Arg[2] = Dead> of MyApp(_: __C.UIScene, willConnectTo: __C.UISceneSession, options: __C.UISceneConnectionOptions) -> () at SceneDelegate.swift:17
->  0x102a85158 <+92>:  mov    x0, x21
    0x102a8515c <+96>:  bl     0x102a85634               ; symbol stub for: objc_release
    0x102a85160 <+100>: mov    x0, x24
    0x102a85164 <+104>: bl     0x102a85634               ; symbol stub for: objc_release
    0x102a85168 <+108>: mov    x0, x19
    0x102a8516c <+112>: bl     0x102a85634               ; symbol stub for: objc_release
    0x102a85170 <+116>: mov    x0, x23
    0x102a85174 <+120>: ldp    x29, x30, [sp, #0x30]
    0x102a85178 <+124>: ldp    x20, x19, [sp, #0x20]
    0x102a8517c <+128>: ldp    x22, x21, [sp, #0x10]
    0x102a85180 <+132>: ldp    x24, x23, [sp], #0x40
    0x102a85184 <+136>: b      0x102a85634               ; symbol stub for: objc_release

我理解为什么我们需要(1),但是(2)的目的是什么?在什么情况下需要这些额外的retainrelease调用?为什么我们不能简单地将所有参数直接转发给 Swift 函数?我猜想有一种方法可以在 Swift 函数的中间释放 Objective-C 对象,但我想不出一个例子来说明这种情况是如何发生的。

标签: objective-cswiftassembly

解决方案


推荐阅读