为了账号安全,请及时绑定邮箱和手机立即绑定

Swift支持反射吗?

Swift支持反射吗?

陪伴而非守候 2019-10-16 13:12:25
Swift支持反射吗?例如,是否有valueForKeyPath:和setValue:forKeyPath:Swift对象类似的东西?实际上,它甚至还具有动态类型系统,例如obj.class在Objective-C中吗?
查看完整描述

3 回答

?
慕雪6442864

TA贡献1812条经验 获得超5个赞

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


向类询问其方法和属性,以及调用方法或设置属性的能力。

交换方法实现的能力。(向所有实例添加功能)。

动态生成和分配新子类的能力。(向给定实例添加功能)

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


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


当不扩展NSObject或使用'@objc'指令时,Swift默认为基于静态和基于vtable的调度。但是,这更快,因为在没有虚拟机的情况下不允许运行时方法拦截。这种拦截是Cocoa的基本组成部分,并且是以下几种类型的功能所必需的:


可可优雅的房地产观察家。(属性观察者会立即使用Swift语言)。

非侵入性地应用横切关注点,例如日志记录,事务管理(即,面向方面的编程)。

代理,消息转发等

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


从NSObject扩展。Xcode中的新类对话框将朝着这个方向发展。

在动态调度的开销导致性能问题的情况下,则可以使用静态调度-例如,在紧密循环中调用具有非常小的主体的方法。

摘要:


Swift的行为类似于C ++,具有快速的静态/ vtable调度和有限的反射。这使其适用于较低级别或性能密集的应用程序,但没有C ++带来的复杂性,学习曲线或错误风险

尽管Swift是一种编译语言,但是方法调用的消息传递风格增加了像Objective-C一样在Ruby和Python等现代语言中发现的内省性和动态性,但没有Objective-C的旧语法。

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


静态:<1.1ns

vtable:〜1.1ns

动态:〜4.9ns

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


同样,dynamic属性允许我们显式指示Swift某个方法应使用动态调度,因此将支持拦截。


public dynamic func foobar() -> AnyObject {

}


查看完整回答
反对 回复 2019-10-16
?
慕工程0101907

TA贡献1887条经验 获得超5个赞

该文档涉及动态类型系统,主要涉及


Type 和 dynamicType


请参见元类型类型(在语言参考中)


例:


var clazz = TestObject.self

var instance: TestObject = clazz()


var type = instance.dynamicType


println("Type: \(type)") //Unfortunately this prints only "Type: Metatype"

现在假设TestObject扩展NSObject


var clazz: NSObject.Type = TestObject.self

var instance : NSObject = clazz()


if let testObject = instance as? TestObject {

    println("yes!") //prints "yes!"

}

当前,没有实现反射。


编辑:我显然是错误的,请参阅stevex的答案。对于内置的属性有一些简单的只读反射,可能允许IDE检查对象内容。


查看完整回答
反对 回复 2019-10-16
  • 3 回答
  • 0 关注
  • 505 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信