iOS MVVM使用要点
一、前言
网上文章真的很多,在此简单的说一些要点和自己的看法。参考以下这篇文章:
二、MVC
MVC 兼顾 View 和 Model 的中间处理,还有很多例如网络请求等很多业务逻辑判断,难免不小心就臃肿厚重。
三、 MVVM
3.1 基本概念和注意事项
-
View和View controller都视为View; -
View不能直接引用Model,而是引用ViewModel; -
ViewModel引用Model,但反过来不行(任何视图本身的引用都不应该放在 ViewModel 中);
ViewModel 是一个放置用户输入验证逻辑,视图显示逻辑,发起网络请求和其他代码的地方。 - 使用
MVVM会轻微的增加代码量,但总体上减少了代码的复杂性。
3.2 使用要点
-
MVVM可以兼容你当下使用的MVC架构; - MVVM 增加你的应用的可测试性;
- MVVM 配合一个绑定机制效果最好(PS:
ReactiveCocoa); -
ViewController尽量不涉及业务逻辑,让ViewModel去做这些事情; -
ViewController只是一个中间人,接收View的事件、调用ViewModel的方法、响应ViewModel的变化; -
ViewModel绝对不能包含视图View(UIKit.h),不然就跟 View 产生了耦合,不方便复用和测试; -
ViewModel之间可以有依赖; -
ViewModel避免过于臃肿,否则重蹈Controller的覆辙,变得难以维护。
3.3 优势
低耦合:View 可以独立于 Model 变化和修改。
可重用性:
可以把视图布局放在一个 ViewModel 里面,让很多 View 重用这段视图逻辑;
也可以把视图布局仍放在 View 里,多个 ViewModel 公用一个布局一致的 View 。
独立开发:开发人员可以专注于业务逻辑和数据的开发 ViewModel,设计人员可以专注于页面设计。
可测试:通常界面是比较难于测试的,而 MVVM 模式可以针对 ViewModel 来进行测试。
3.4 弊端
Bug 很难被定位:
首先,很多人觉得这样查找 bug 更加麻烦了,因为毕竟要多跳转一层 ViewModel 。
但是当你熟练使用 MVVM 后,你找到 View 使用的 ViewModel,然后清楚的定位数据和逻辑问题在 ViewModel 中。
这里就要强调上面说的一定要层次分明的使用 ViewModel,不能是 ViewModel 中引用 View,View 中又包含该放在 ViewModel 中的逻辑,这样的话 bug 自然难以定位了。
ReactiveCocoa:
MVVM 一致强调和 RAC 同时使用会更加方便。
不使用 RAC :ViewModel 处理完数据需要刷新 View 等操作都是通过 Block 回调来实现,不免是有些麻烦的。
使用 RAC :在 View 初始化的时候就和 ViewModel 进行绑定,只要 ViewModel 的数据有所变化,便自动更新 View 。
RAC 缺点:数据绑定使得一个位置的 Bug 被快速传递到别的位置,要定位原始出问题的地方就变得不那么容易了。
四、ReactiveCocoa
响应式编程思想:不需要考虑调用顺序,只需要知道考虑结果,类似于蝴蝶效应,产生一个事件,会影响很多东西,这些事件像流一样的传播出去,然后影响结果,借用面向对象的一句话,万物皆是流。
代表:KVO运用。
ReactiveCocoa 常见宏:
- RAC(TARGET, [KEYPATH, [NIL_VALUE]]):用于给某个对象的某个属性绑定。
// 只要文本框文字改变,就会修改label的文字
RAC(self.labelView,text) = _textField.rac_textSignal;
- RACObserve(self, name):监听某个对象的某个属性,返回的是信号。
[RACObserve(self.view, center) subscribeNext:^(id x) {
NSLog(@"%@",x);
}];