Swift泛型类型属性和方法

时间:2016-01-11 12:55:00

标签: ios swift generics types controller

如何在属性中存储泛型类型,然后使用该类型属性传入方法?

我有工厂,其方法接收视图控制器类型但返回该视图控制器的实例(容器负责处理)。

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)!
}

}

我有这样的财产

var destinationViewController: UIViewController.Type { get }

现在我想做点什么:

factory.getViewController(self.destinationViewController)

我将destinationViewController声明为LoginViewController.self

但它没有像那样工作。奇怪的是,如果我直接这样做它会起作用:

factory.getViewController(LoginViewController.self)

任何帮助?感谢

1 个答案:

答案 0 :(得分:2)

如果没有看到resolve的代码,就无法说出它崩溃的原因,但我有个好主意。我怀疑你错误地认为泛型类型参数和运行时类型参数之间的区别。考虑这个简化的代码。

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 !!!!!!

为什么最后一个案例是Super / Sub?因为printType<T>在编译时被解析。它只关注定义:

func printType<T>(type: T.Type)
let type: Super.Type

printType(type)

为了完成这项工作,我需要一个TT.TypeSuper.Type相同。好吧,那是Super。所以这被编译为:

printType<Super>(type)

现在,在运行时,我们发现type等于Sub.self,这是Super.type的子类型,所以没关系。我们将其传递给printType<Super>并获得您正在看到的回复。

所以可能是resolve的内部,你在某个地方使用T,而你想要使用type,并且你正试图“解决”UIViewController,可能会返回nil。