Swift继承了Objective-C的元类概念:类本身也被认为是对象。类Foo
的对象类是Foo.self
,类型为Foo.Type
。如果Foo
继承自Bar
,则Foo.self
也可以分配给Bar.Type
类型的变量。这至少有两个好处:
我现在特别关注第二个。只是为了确保每个人都理解我所追求的,这是一个例子:
class BaseFoo {
var description: String { return "BaseFoo" }
}
class DerivedFoo: BaseFoo {
override var description: String { return "DerivedFoo" }
}
let fooTypes: [BaseFoo.Type] = [BaseFoo.self, DerivedFoo.self] // metaclass magic!
for type in fooTypes {
let object: BaseFoo = type() // metaclass magic!
println(object)
}
现在,我有一个AnyClass
个对象数组(任何元类实例都可以分配给AnyClass
,就像任何对象都可以分配给AnyObject
)一样,我想找到哪些实现给定的协议。该协议将声明一个初始化器,我将像上面的例子中那样实例化该类。例如:
protocol Foo {
init(foo: String)
}
class Bar: Foo {
required init(foo: String) { println("Bar initialized with \(foo)") }
}
class Baz {
required init() { println("I'm not a Foo!") }
}
let types: [AnyClass] = [Bar.self, Baz.self]
到目前为止一切顺利。现在,问题在于确定类是否实现了协议。由于元类实例是多态的,我希望能够转换它们。但是,我显然错过了一些东西,因为Swift不会让我写下这个:
for type in types {
if let fooType = type as? Foo.Type {
let obj = fooType(foo: "special snowflake string")
}
}
我得到的编译错误是:
错误:'Foo'与'AnyObject'
不同
有没有办法确定元类实例是否代表实现协议的类,有没有办法将该实例强制转换为协议类型?
我尝试将Foo
声明为类协议,但显然还不够。
编辑:我刚尝试使用Any
类型,虽然它不会导致语法错误,但它会导致Swift编译器崩溃。
答案 0 :(得分:5)
从Xcode 7 beta 2和Swift 2开始,它已得到修复。你现在可以写:
for type in types {
if let fooType = type as? Foo.Type {
// in Swift 2 you have to explicitly call the initializer of metatypes
let obj = fooType.init(foo: "special snowflake string")
}
}
或者,如果您只想type
作为Foo.Type
类型,则可以使用for case
for case let type as Foo.Type in types {
let obj = type.init(foo: "special snowflake string")
}