Swift类内省和generics

我试图dynamic创build一个基于class实例使用generics,但是我遇到了类反思的困难。

以下是问题:

  • 有没有一个相当于Obj-C的self.class的Swift?
  • 有没有办法使用AnyClass结果实例化一个类?
  • 有没有办法获得AnyClass或以其他方式严格从通用参数Tinput信息? (类似于C#的typeof(T)语法)

那么,作为一个, [NSString class]的Swift等价物是.self (请参阅Metatype文档 ,虽然它们很薄)。

事实上, NSString.class甚至不工作! 你必须使用NSString.self

 let s = NSString.self var str = s() str = "asdf" 

同样的,一个快速的课我尝试…

 class MyClass { } let MyClassRef = MyClass.self // ERROR :( let my_obj = MyClassRef() 

嗯…错误说:

游乐场执行失败:错误::16:1:错误:构造types为“X”的对象具有元types值需要一个“@required”初始值设定项

  Y().me() ^ <REPL>:3:7: note: selected implicit initializer with type '()' class X { ^ 

我花了一段时间才弄清楚这意味着什么…事实上,它希望类有一个@required init()

 class X { func me() { println("asdf") } required init () { } } let Y = X.self // prints "asdf" Y().me() 

一些文档将其称为.Type ,但MyClass.Type在操场中给了我一个错误。

以下是如何使用NSClassFromString 。 你必须知道你将要结束的超类。 这里有一个超类 – 子类对,知道如何描述自己的println

 @objc(Zilk) class Zilk : NSObject { override var description : String {return "I am a Zilk"} } @objc(Zork) class Zork : Zilk { override var description : String {return "I am a Zork"} } 

注意使用特殊的@obj语法来指定这些类的Objective-C名称; 这是至关重要的,因为否则我们不知道指定每个类的消逝的string。

现在我们可以使用NSClassFromString来创buildZork类或Zilk类,因为我们知道我们可以将它作为一个NSObjectinput,而不会在以后崩溃:

 let aClass = NSClassFromString("Zork") as NSObject.Type let anObject = aClass() println(anObject) // "I am a Zork" 

而且是可逆的。 println(NSStringFromClass(anObject.dynamicType))也可以。

如果我正在阅读文档,如果您处理实例并且想要返回与您已经提供的对象相同types的新实例,并且可以使用init()构造Type(types),那么您可以:

 let typeOfObject = aGivenObject.dynamicType var freshInstance = typeOfObject() 

我很快用String来testing它:

 let someType = "Fooo".dynamicType let emptyString = someType() let threeString = someType("Three") 

哪些工作正常。

迅速3

 object.dynamicType 

已弃用。

而是使用:

 type(of:object) 

Swift实现比较types

 protocol Decoratable{} class A:Decoratable{} class B:Decoratable{} let object:AnyObject = A() object.dynamicType is A.Type//true object.dynamicType is B.Type//false object.dynamicType is Decoratable.Type//true 

注意:请注意,它也适用于该对象可能或不可以扩展的协议

终于有了一些工作。 它有点懒,但即使NSClassFromString()路由不适合我…

 import Foundation var classMap = Dictionary<String, AnyObject>() func mapClass(name: String, constructor: AnyObject) -> () { classMap[name] = constructor; } class Factory { class func create(className: String) -> AnyObject? { var something : AnyObject? var template : FactoryObject? = classMap[className] as? FactoryObject if (template) { let somethingElse : FactoryObject = template!.dynamicType() return somethingElse } return nil } } import ObjectiveC class FactoryObject : NSObject { @required init() {} //... } class Foo : FactoryObject { class override func initialize() { mapClass("LocalData", LocalData()) } init () { super.init() } } var makeFoo : AnyObject? = Factory.create("Foo") 

和宾果,“makeFoo”包含一个Foo实例。

缺点是你的类必须从FactoryObject驱动,他们必须有Obj-C +初始化方法,所以你的类被全局函数“mapClass”自动插入到类映射中。

下面是另一个例子,显示了类的层次结构的实现,类似于接受的答案,更新了第一个版本的Swift。

 class NamedItem : NSObject { func display() { println("display") } required override init() { super.init() println("base") } } class File : NamedItem { required init() { super.init() println("folder") } } class Folder : NamedItem { required init() { super.init() println("file") } } let y = Folder.self y().display() let z = File.self z().display() 

打印这个结果:

 base file display base folder display