Swift如何创建像UIViewController

时间:2017-08-07 12:02:22

标签: ios swift generics mvp

我想删除重复的代码,所以我想创建一个简单的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功能中达到了极限?

0 个答案:

没有答案