最近,我正在阅读有关依赖反转的原理,该原理指出高级模块不应依赖于低级模块,它们都应依赖于抽象。
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()
}
}
following dependency inversion principle, i am able to communicate between viewcontroller -> Viewmodel.
my question is, how to communicate in reverse direction ? ie. form view model to view controller ?
i am thinking, by creating another protocol, and viewcontroller implements that protocol....
how to communicate in reverse direction ? ie. form view model to view controller ?
您使用闭包返回呼叫。
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?()
}
}
使用委托模式从ViewModel到View进行通讯就可以了,只要ViewModel不拥有View,即没有对View的强引用。
作为替代解决方案,您也可以查看观察者模式,以将消息从ViewModel传递到View。实际上,这就是RxSwift之类的库为您提供的。
[如果您查看了显示依赖关系反转的类图,则对于MVVM,从ViewModel到View的关联始终显示在虚线中,并带有指向View的箭头。这只是意味着ViewModel知道View,但是对它没有任何强引用。
添加一个闭包作为完成处理程序
protocol ViewControllerProtocol {
func saveButtonTapped(completionHandler: ()->())
}
这是您现在可以使用的方式:-
@IBAction func btnSaveTapped(_ sender: Any) {
vm?.saveButtonTapped { [weak self] in
/// From ViewModel -> ViewController
}
}
[如果要在该闭包内使用viewController,请不要忘记添加捕获列表以避免保留周期。