Kha*_*yen 113 reflection ios swift
斯威夫特是否支持反思?例如,有什么样valueForKeyPath:和setValue:forKeyPath:对雨燕的对象?
实际上它甚至有一个动态类型系统,类似于obj.classObjective-C?
ste*_*vex 85
看起来有一些反思支持的开始:
class Fruit {
var name="Apple"
}
reflect(Fruit()).count // 1
reflect(Fruit())[0].0 // "name"
reflect(Fruit())[0].1.summary // "Apple"
Run Code Online (Sandbox Code Playgroud)
来自mchambers gist,在这里:https://gist.github.com/mchambers/fb9da554898dae3e54f2
Jas*_*ues 45
如果一个类扩展NSObject,那么Objective-C的所有内省和动态都会起作用.这包括:
此功能的一个缺点是支持Swift可选值类型.例如,Int属性可以枚举和修改,但Int?属性不能.可以使用reflect/MirrorType部分枚举可选类型,但仍未修改.
如果一个类没有扩展NSObject,那么只有新的,非常有限的(并且正在进行中)反射工作(参见reflect/MirrorType),这增加了向实例询问其类和属性的有限能力,但没有上述任何附加功能.
当不扩展NSObject或使用'@objc'指令时,Swift默认为基于static和vtable的调度.然而,这更快,在没有虚拟机的情况下不允许运行时方法拦截.此拦截是Cocoa的基本组成部分,是以下类型功能所必需的:
因此,它推荐使用Swift实现的Cocoa/CocoaTouch应用程序中的clases:
摘要:
参考数据:方法调用的执行开销:
(实际性能取决于硬件,但比率将保持相似).
此外,动态属性允许我们明确地指示Swift方法应该使用动态分派,因此将支持拦截.
public dynamic func foobar() -> AnyObject {
}
Run Code Online (Sandbox Code Playgroud)
文档讲的是动态类型系统,主要是关于
Type 和 dynamicType
例:
var clazz = TestObject.self
var instance: TestObject = clazz()
var type = instance.dynamicType
println("Type: \(type)") //Unfortunately this prints only "Type: Metatype"
Run Code Online (Sandbox Code Playgroud)
现在假设TestObject延伸NSObject
var clazz: NSObject.Type = TestObject.self
var instance : NSObject = clazz()
if let testObject = instance as? TestObject {
println("yes!") //prints "yes!"
}
Run Code Online (Sandbox Code Playgroud)
目前,没有实施反思.
编辑:我显然错了,看到史蒂夫斯的回答.对于内置属性,有一些简单的只读反射,可能允许IDE检查对象内容.
似乎Swift反射API目前不是Apple的高优先级.但是,除了@stevex 答案有标准库,帮助其他功能.
从beta 6开始,_stdlib_getTypeName获取变量的错位类型名称.将其粘贴到空的操场上:
import Foundation
class PureSwiftClass {
}
var myvar0 = NSString() // Objective-C class
var myvar1 = PureSwiftClass()
var myvar2 = 42
var myvar3 = "Hans"
println( "TypeName0 = \(_stdlib_getTypeName(myvar0))")
println( "TypeName1 = \(_stdlib_getTypeName(myvar1))")
println( "TypeName2 = \(_stdlib_getTypeName(myvar2))")
println( "TypeName3 = \(_stdlib_getTypeName(myvar3))")
Run Code Online (Sandbox Code Playgroud)
输出是:
TypeName0 = NSString
TypeName1 = _TtC13__lldb_expr_014PureSwiftClass
TypeName2 = _TtSi
TypeName3 = _TtSS
Run Code Online (Sandbox Code Playgroud)
Ewan Swick的博客文章有助于破译这些字符串:
例如_TtSi代表Swift的内部Int类型.
小智 5
您可能需要考虑使用toString().它是公共的,与_stdlib_getTypeName()的工作原理相同,区别在于它也适用于AnyClass,例如在Playground输入
class MyClass {}
toString(MyClass.self) // evaluates to "__lldb_expr_49.MyClass"
Run Code Online (Sandbox Code Playgroud)
reflectSwift 5 中没有关键字,现在您可以使用
struct Person {
var name="name"
var age = 15
}
var me = Person()
var mirror = Mirror(reflecting: me)
for case let (label?, value) in mirror.children {
print (label, value)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
33539 次 |
| 最近记录: |