问题
How do I store generic type in property and then use that type property to pass in method?
I have factory whose method receives view controllers type but returns instance of that view controller (container takes care of that).
public protocol ViewControllerFactoryProtocol {
func getViewController<T: UIViewController>(type: T.Type) -> UIViewController
}
public class ViewControllerFactory: ViewControllerFactoryProtocol {
private let container: Container
public init(container: Container) {
self.container = container
}
public func getViewController<T: UIViewController>(type: T.Type) -> UIViewController {
return self.container.resolve(type)!
}
}
And I have property like this
var destinationViewController: UIViewController.Type { get }
Now I would like to do something like:
factory.getViewController(self.destinationViewController)
where I declare destinationViewController as LoginViewController.self
But its not working like that. Weird thing is that it is working if I do it directly:
factory.getViewController(LoginViewController.self)
Any help?? Thanks
回答1:
Without seeing the code for resolve it's not possible to say why it's crashing, but I have a good idea. I suspect you're mistaking the difference between generic type parameters and runtime type parameters. Consider this simplified code.
func printType<T>(type: T.Type) {
print("T is \(T.self)")
print("type is \(type)")
}
class Super {}
class Sub: Super {}
printType(Super.self) // Super/Super. Good.
printType(Sub.self) // Sub/Sub. Good.
let type: Super.Type = Sub.self
printType(type) // Super/Sub !!!!!!
Why is the last case Super/Sub? Because printType<T> is resolved at compile time. It looks just at the definitions:
func printType<T>(type: T.Type)
let type: Super.Type
printType(type)
To make this work, I need a T such that T.Type is the same as Super.Type. Well, that's Super. So this gets compiled as:
printType<Super>(type)
Now at runtime, we see that type is equal to Sub.self, which is a subtype of Super.type, so that's ok. We pass it along to printType<Super> and get the response you're seeing.
So probably internal to resolve, you're using T somewhere that you wanted to use type, and that you're trying to "resolve" UIViewController, which probably returns nil.
来源:https://stackoverflow.com/questions/34722101/swift-generic-type-property-and-method