SWIFT支持反射吗?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (35)

Swift支持反射吗?例如,有什么样valueForKeyPath:setValue:forKeyPath:对雨燕的对象?

实际上它甚至有一个动态类型系统,就像obj.class在Objective-C中一样?

提问于
用户回答回答于

看起来有一些反射支持的开始:

class Fruit {
    var name="Apple"
}

reflect(Fruit()).count         // 1
reflect(Fruit())[0].0          // "name"
reflect(Fruit())[0].1.summary  // "Apple"
用户回答回答于

如果一个类扩展了NSObject,那么Objective-C的所有内省和活力都可以工作。这包括:

  • 向类请求其方法和属性以及调用方法或设置属性的能力。
  • 交换方法实现的能力。(为所有实例添加功能)。
  • 即时生成和分配新子类的能力。(给给定实例添加功能)

此功能的一个缺点是支持Swift可选值类型。例如,Int属性可以被枚举和修改,但是Int?属性不能。可选类型可部分使用reflect / MirrorType枚举,但仍未修改。

如果一个类没有扩展NSObject,那么只有新的,非常有限的(并且正在进行?)反射工作(参见reflect / MirrorType),这增加了向实例询问其类和属性的有限能力,但是没有上述其他功能。

当不扩展NSObject或使用'@objc'指令时,Swift默认为基于静态和基于vtable的调度。但是,如果虚拟机不允许运行时方法拦截,则速度会更快。这种拦截是Cocoa的一个基本部分,对于以下类型的功能是必需的:

  • 可可优雅的财产观察员。(属性观察者可以直接使用Swift语言)。
  • 无创地应用横切关注点,如日志记录,事务管理(即面向方面编程)。
  • 代理,信息转发等

因此,建议使用Swift实现Cocoa / CocoaTouch应用程序中的类:

  • 从NSObject扩展。Xcode中的新类对话框在这个方向上转向。
  • 例如,在动态调度的开销导致性能问题的地方,可以使用静态调度 - 例如,在调用具有非常小的主体的方法的紧密循环中。

概要:

  • Swift可以像C ++一样运行,具有快速的静态/虚表调度和有限的反射。这使它适用于较低级别或性能密集型应用程序,但没有与C ++相关的复杂性,学习曲线或错误风险
  • 虽然Swift是一种编译语言,但方法调用的消息传递风格增加了现代语言(如Ruby和Python)中的内省和动态,就像Objective-C一样,但没有Objective-C的传统语法。

参考数据:方法调用的执行开销:

  • 静态:<1.1ns
  • vtable:〜1.1ns
  • 动态:〜4.9ns

(实际性能取决于硬件,但比率将保持相似)。

此外,动态属性允许我们明确指示Swift应该使用动态分派方法,因此将支持拦截。

public dynamic func foobar() -> AnyObject {
}

扫码关注云+社区