我想删除重复的代码,所以我想创建一个简单的MVP基本视图控制器,它将模型,视图和演示者类型绑定在一起并自动连接它们,例如:
class BaseMvpViewController<M: MvpModel, V: MvpView, P: MvpPresenter>: UIViewController {
我的模型和视图是空协议:
protocol MvpModel {}
protocol MvpView: class {} // class is needed for weak property
和演示者看起来像这样:
protocol MvpPresenter {
associatedtype View: MvpView
weak var view: View? { get set }
func onAttach(view: View)
func onDetach(view: View)
}
这是我的全部BaseMvpViewController
:
class BaseMvpViewController<M: MvpModel, V, P: MvpPresenter>: UIViewController, MvpView {
typealias View = V
var model: M? = nil
var presenter: P!
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
deinit {
presenter.onDetach(view: self as! View)
}
override func viewDidLoad() {
createPresenter()
super.viewDidLoad()
presenter.onAttach(view: self as! View)
}
func createPresenter() {
guard presenter != nil else {
preconditionFailure("Presenter was not created or it was not assigned into the `presenter` property!")
}
}
}
问题是V
必须没有协议,即不能V: MvpView
。否则,VC的特定实现必须具有类/结构,而不仅仅是MvpView
的协议。我的所有观点都只是协议,我的VC会实现它们,例如
class MyViewController: BaseMvpViewController<MyModel, MyView, MyPresenter>, MyView
现在,编译器在onAttach()
和onDetach()
方法中抱怨&#34;参数类型&#39; V&#39;不符合预期的类型&#39; MvpView&#39;&#34;
所以我试了一个扩展名:
extension BaseMvpViewController where V: MvpView {
override func viewDidLoad() {
presenter.onAttach(view: self as! View)
}
}
又一个编译错误:&#34;无法调用onAttach&#39;使用类型&#39;(视图:V)&#39;&#34;的参数列表。还有另一个小的编译错误&#34;约束扩展的成员不能被声明为@ objc&#34;我在扩展程序中override func viewDidLoad()
的位置。这可以通过我自己的方法修复,并从自定义类中的viewDidLoad
调用该方法。知道怎么做到我想要的吗?
这是一个类似/相同的问题,如Using some protocol as a concrete type conforming to another protocol is not supported,但从那时起Swift世界可能已经有所改进。或者我是否真的在当前的Swift功能中达到了极限?