【问题标题】:How does iOS Swift Runtime workiOS Swift 运行时如何工作
【发布时间】:2016-09-15 20:46:52
【问题描述】:

ObjC中,使用Messagingstatic bindingdynamic typingdynamic bindingdynamic method resolutiondynamic loadingintrospector等。

重要的是,核心方法 objc_msgSend 负责获取您要发送的选择器和您要发送到的对象,并在类方法表中查找它们以准确确定应该使用哪段代码处理它。

我担心的是:

  1. Swift 是否在运行时执行类似于 ObjC 的操作?

  2. Swift runtime 如何找到某个对象/类方法的实现代码?

  3. ObjCclassesobjects 在运行时编译为一些runtime types,例如C struct。那么classesobjects 在运行时在Swift 中编译成什么?

  4. Swift runtime 有类似class / meta class / isa pointer / super pointer 的东西吗?

【问题讨论】:

  • 你能举个例子吗?
  • @Boris 我的回答与#1 & #2 有关。关于#3 和#4,我确信 Swift 肯定有一些东西,但并不稳定。最初计划在 Swift 3.0 版本中稳定 ABI,但平面已更改:infoq.com/news/2016/05/swift-3-no-stable-abi

标签: ios swift runtime


【解决方案1】:

简而言之,方法调用分派有动态和静态类型。

  1. 静态 - 要调用的函数地址在编译时确定,因此此类调用的费用类似于 C 函数调用。此机制用于private 方法或final 类方法调用调度。

  2. 动态调度是一种机制,它允许实现 OOP 的多态概念——要调用的函数地址是在运行时确定的。 Swift 有它的两个子类型:

    2.1。 Obj-C - 你已经在问题中描述过。当对象继承自 NSObject 或调用方法有@objc 前缀时使用此机制。

    2.2。基于虚拟表(如在 C++ 中) - 有类似的见证表。它在方法调用调度期间所做的只是单个算术运算 - 根据基类见证表中的函数偏移量和对象类见证表位置计算实际函数地址。所以与 Obj-C 相比,这是一个相对便宜的操作。它解释了为什么“纯”Swift 接近于 C++ 性能。

如果你没有用private 关键字标记你的方法,或者你的类不是final,同时你的类是“纯”Swift(它不继承NSObject),那么就会使用这种基于虚拟表的机制。这意味着默认情况下所有方法都是virtual

附: 证明我对“类型”的看法的有用链接:

https://developer.apple.com/swift/blog/?id=27

“子类型”的解释是基于我的理解。

【讨论】:

  • 很好的解释。静态标记的方法运行时不也是静态的吗?
猜你喜欢
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 2012-04-22
  • 1970-01-01
  • 2020-08-16
  • 1970-01-01
  • 1970-01-01
  • 2012-08-19
相关资源
最近更新 更多