Swift generic type property and method

萝らか妹 提交于 2019-12-11 00:40:20

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!