最近我正在阅读有关依赖反转的原理,该原理指出高级模块不应依赖于低级模块,它们都应依赖于抽象。
protocol ViewControllerProtocol {
func saveButtonTapped()
}
struct ViewModel : ViewControllerProtocol{
func saveButtonTapped() {
//save data...
print("forward save request")
}
func statusArrived(){
// inform viewcontroller about updating UI
}
}
class ViewController: UIViewController {
private var vm : ViewControllerProtocol?
required init(viewmodel : ViewModel){
self.vm = viewmodel
super.init(nibName: nil, bundle:nil)
}
@IBAction func btnSaveTapped(_ sender: Any) {
vm?.saveButtonTapped()
}
}
遵循依赖性反转原则,我能够在viewcontroller-> Viewmodel之间进行通信。
我的问题是,如何反向交流?即。形成视图模型以查看控制器? 我在想,通过创建另一个协议,viewcontroller实现该协议。...
如何反向交流?即。表单视图模型以查看控制器?
答案 0 :(得分:0)
您可以使用闭包来返回调用。
class ViewController: UIViewController {
private var vm : ViewControllerProtocol?
required init(viewmodel : ViewModel){
self.vm = viewmodel
super.init(nibName: nil, bundle:nil)
self.vm.savedSuccessfully = {
// do stuff
}
}
@IBAction func btnSaveTapped(_ sender: Any) {
vm?.saveButtonTapped()
}
}
struct ViewModel : ViewControllerProtocol{
var savedSuccesfully: (() -> ())?
func saveButtonTapped() {
//save data...
print("forward save request")
}
func statusArrived(){
// inform viewcontroller about updating UI
savedSuccesfully?()
}
}
答案 1 :(得分:0)
只要ViewModel不拥有View,就可以使用委托模式从ViewModel到View进行通信,即没有对View的强引用。
作为替代解决方案,您还可以查看Observer Pattern,将消息从ViewModel传递到View。实际上,这就是RxSwift之类的库为您提供的。
如果您查看了显示依赖关系反转的类图,那么在MVVM的情况下,从ViewModel到View的关联始终显示在虚线中,并带有指向View的箭头。这只是意味着ViewModel知道View,但是对它没有任何强引用。
答案 2 :(得分:0)
将结束添加为完成处理程序
protocol ViewControllerProtocol {
func saveButtonTapped(completionHandler: ()->())
}
实施
struct ViewModel : ViewControllerProtocol{
func saveButtonTapped(completionHandler: () -> ()) {
print("forward save request")
completionHandler()
}
}
这是您现在可以使用的方式:-
@IBAction func btnSaveTapped(_ sender: Any) {
vm?.saveButtonTapped { [weak self] in
/// From ViewModel -> ViewController
}
}
如果您要在该闭包内使用viewController,请不要忘记添加捕获列表以避免保留周期。