我正在尝试编写一个简单的 MVP 模式以在我的应用程序中遵循,因此我编写了两个协议(protocol)来定义 View Controller 和演示者:
protocol PresenterType: class {
associatedtype ViewController: ViewControllerType
var viewController: ViewController? { get set }
func bind(viewController: ViewController?)
}
protocol ViewControllerType: class {
associatedtype Presenter: PresenterType
var presenter: Presenter { get }
init(presenter: Presenter)
}
在定义了这些之后,我开始编写一些 RootViewController
和 RootViewPresenter
。后者看起来像:
protocol RootViewControllerType: ViewControllerType {
}
final class RootPresenter<VC: RootViewControllerType>: PresenterType {
weak var viewController: VC?
func bind(viewController: VC?) {
self.viewController = viewController
}
}
到目前为止,一切都符合要求并且很好,但是当我开始像这样实现 View Controller 时:
protocol RootPresenterType: PresenterType {
}
final class RootViewController<P: RootPresenterType>: UIViewController, ViewControllerType {
let presenter: P
init(presenter: Presenter) {
self.presenter = presenter
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
presenter.bind(viewController: self)
}
}
我立即收到以下错误消息:
Cannot convert value of type 'RootViewController
' to expected argument type '_?'
我知 Prop 有关联类型的 protocol
会引入一些限制,但这个示例非常简单,我无法让它工作。是否有可能实现我想要的东西,或者我是否必须寻找其他一些不那么 Swifty 的模式?
最佳答案
由于 PresenterType
和 ViewControllerType
协议(protocol)的各自关联类型之间存在循环依赖关系,我认为您无法实现您想要实现的目标。
考虑一下,如果上面的可疑代码确实编译了...您将如何实例化 RootPresenter
或 RootViewController
类?因为两者相互依赖,所以您最终会遇到如下错误:
如您所见,由于关联类型,编译器无法完全解析泛型参数。
我认为最好的办法是从一个或两个协议(protocol)中删除关联类型。例如,从 PresenterType
协议(protocol)中删除关联类型并更新 RootPresenter
类会打破循环依赖并允许您的代码正常编译。
protocol PresenterType: class {
var viewController: UIViewController? { get set }
func bind(viewController: UIViewController?)
}
final class RootPresenter: PresenterType {
weak var viewController: UIViewController?
func bind(viewController: UIViewController?) {
self.viewController = viewController
}
}
关于swift - 在泛型函数中使用协议(protocol)的关联类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53507364/