Swift inherited the concept of the Objective-C metaclass: the classes themselves are also considered objects. The class class Foo is Foo.self , and it is of type Foo.Type . If Foo inherits from Bar , then Foo.self can also be assigned to a variable of type Bar.Type . This has at least two advantages:
- it allows you to override "static methods";
- it is easy to instantiate an unknown class with a safe type and without using reflection.
I'm looking at the second now. To be sure everyone understands what I need, here is an example:
class BaseFoo { var description: String { return "BaseFoo" } } class DerivedFoo: BaseFoo { override var description: String { return "DerivedFoo" } } let fooTypes: [BaseFoo.Type] = [BaseFoo.self, DerivedFoo.self]
Now I have an array of AnyClass objects (any instance of a metaclass can be assigned to AnyClass , just like any object can be assigned to AnyObject ), and I want to find which ones implement this protocol, the Protocol will declare an initializer, and I would instantiate the class. as in the example above. For example:
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]
So far so good. The problem now is whether the class implements the protocol. Since metaclass instances are polymorphic, I expect that I can distinguish them. However, I obviously missed something because Swift would not let me write this:
for type in types { if let fooType = type as? Foo.Type { let obj = fooType(foo: "special snowflake string") } }
Compiler Error:
error : "Foo" is not identical to "AnyObject"
Is there a way to determine if a metaclass instance represents a class that implements the protocol, and is there a way to pass this instance to the protocol type?
I tried to declare Foo as a class protocol, but apparently this is not enough.
EDIT : I just tried with type Any , and although it does not cause a syntax error, it throws a Swift compiler.