"an array of protocol-compliant classes" can be declared as Array<TheProtocol.Type> .
You can:
var array: Array<ControllerConstructorProtocol.Type> = [ MyConstructor.self, MyOtherConstructor.self, ]
But...
array[0].construct() // ^ error: accessing members of protocol type value 'ControllerConstructorProtocol.Type' is unimplemented
The invocation method on the "not implemented" element.
At this point, you should declare the protocol as @objc and call the method through AnyClass . Moreover, for some reason, we cannot directly use array[0] in AnyClass , instead we must pass it to Any , then AnyClass .
@objc protocol ControllerConstructorProtocol { class func construct() -> UIViewController? } var array: Array<ControllerConstructorProtocol.Type> = [ MyConstructor.self, MyOtherConstructor.self, ] let vc = (array[0] as Any as AnyClass).construct()
Note. The casting task has been fixed in Swift 1.2 / Xcode 6.3. But "unrealized" is "not applicable": (
Just random ideas:
It depends on your actual use case, but in this particular case, the closure array ()-> UIViewController? :
var array: [() -> UIViewController?] = [ MyConstructor.construct, MyOtherConstructor.construct, ] let vc = array[0]()
If you have several methods, you might want to use a wrapper with a protocol type.
protocol ControllerConstructorProtocol { class func construct() -> UIViewController? class func whoami() -> String } struct ControllerConstructorWrapper { private let _construct: () -> UIViewController? private let _whoami: () -> String init<T: ControllerConstructorProtocol>(_ t:T.Type) { _construct = { t.construct() } _whoami = { t.whoami() } } func construct() -> UIViewController? { return _construct() } func whoami() -> String { return _whoami() } } var array: [ControllerConstructorWrapper] = [ ControllerConstructorWrapper(MyConstructor), ControllerConstructorWrapper(MyOtherConstructor), ] let who = array[0].whoami() let vc = array[0].construct()
rintaro
source share