我正在尝试编写一个简单的MVP模式以遵循我的应用程序,因此我编写了两个porotocol来定义View Controller和Presenters:
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)
}
}
我立即收到以下错误消息:
无法将类型'RootViewController
'的值转换为预期的参数类型'_?'
我知道具有关联类型的protocol
可能会带来一些限制,但是此示例非常简单,我无法使其正常工作。是否有可能实现我想要的目标,还是必须寻找其他一些不那么迅速的模式?
答案 0 :(得分:2)
由于PresenterType
和ViewControllerType
协议各自相关类型之间的循环依赖性,我认为您要实现的目标是不可能的。
请考虑一下,如果 did 以上的可疑代码编译了……您将如何实例化RootPresenter
或RootViewController
类?因为两者相互依赖,所以最终会出现如下错误:
如您所见,由于类型相关,编译器无法完全解析通用参数。
我认为您最好的选择是从一个或两个协议中删除关联的类型。例如,从PresenterType
协议中删除关联的类型并更新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
}
}