1. MVC
MVC之间的关系,如图:
View视图:用户界面
Model模型:数据保存
Controller控制器:业务逻辑
Controller 负责将 Model 的数据用 View 显示出来,他们之间数据的交互如下图:
1.1 View和Controller的交互
1)第一种方式:action-target用来负责传递特定的事件;(比如按钮点击事件,是View来接收的,但是处理这个事件的应该是Controller,所以View把这个事件传递给了Controller,如何传递的呢,如图,View上面的action就是这个事件,Controller上面的target就是靶子,View究竟要把事件传递给谁?它被规定了传递给靶子,Controller实际上就是靶子,View只负责传递事件,不负责关心靶子是谁。)
2)第二种方式:协议-委托方式,委托有两种——代理和数据源。什么是代理,就是专门处理should、will、did事件的委托;什么是数据源,就是专门处理data、count等等的委托。
2.1)delegate-protocol提前约定了对一些事件的处理规则,当被规定的事件发生后,就按照协议的规定来进行处理。协议委托可以通过协议方法的参数由V向C传值。比如cell点击事件的协议方法,tableView通过indexPath参数告诉C是哪个cell被点击了。
2.2)dataSource-protocol用来通过回调的形式动态通过数据绘制界面。dataSource通过回调的形式,让绘制逻辑由dataSource控制(dataSource协议方法的实现)而绘制过程则由V来进行(dataSource协议方法的调用)。调用方V通过参数把值传给实现方dataSource,实现方通过返回值把值回传给调用方,这样V就通过不停的调用dataSource方法获取它所需要的绘制信息,最终绘制出界面。
1.2 Model和Controller的交互
Model: 就是管理数据的模块,它需要去获取数据(可以在本地数据库,也可以在服务器数据库),将获取到的数据传递给 Controller,Controller并不关心它到底去哪里获取的数据,Controller 需要关心的是它何时将数据全部获取成功?Model管理的数据是否发生了变化?(检测这种变化是为了将最新的数据传递给V)。
在OC中有一种机制恰好就是来解决“一个对象想要关心另一个对象的属性是否发生了变化”的问题,它叫做KVO。KVO叫做键值观察,它让一个对象作为观察者去观察另一个对象的由某个键值路径所代表的属性,一旦这个属性发生了变化,那么系统就会调用观察者的一个方法叫做observingValueForKeyPath...。 图上还标明了一个东西叫做Notification也就是通知,比如你想网络请求失败以后应该弹出提示框,或者自动登录打开App请求首页数据失败想要返回到登录页面重新登录,这样的操作肯定应该在C里面进行,所以M的网络请求一旦失败,就可以向C发送一个通知,来告诉C,网络请求失败。
2. 为什么会出现MVVM
在MVC模式中,我们需要将数据显示给用户,所以有了V;需要一个模块存取数据,所以有了M;需要将M的数据在V上显示出来,所以出现了C。在这个过程中,忽略了一个重要的操作——就是数据解析。(数据解析:把原始数据转换成View能直接使用的数据。例如:网络请求获取下来一个字典(往往使用JSON格式封装的数据都会以字典的形式获取到),这个字典将作为原始数据存放在Model中。而我们的Controller实际上需要字典中某个key对应的一个数组,然后用这个数组来控制一个View的显示)这些都表明,在MVC模式中是将数据的解析操作放在了Controller中进行处理,在MVC出生的年代,手机APP的数据往往都比较简单,没有现在那么复杂,所以那时的数据解析很可能一步就解决了。但是随着产品功能越来越复杂,数据结构也越来越复杂,所以数据解析也就没那么简单了。如果我们继续按照MVC的设计思路,将数据解析的部分放到了Controller里面,那么Controller就将变得相当臃肿。还有相当重要的一点:Controller被设计出来并不是处理数据解析的。
Controller能做的事情是根据UIKit框架API对UIViewController头文件的定义: 1、self.view用来作为所有视图的容器;2、管理自己的生命周期;3、处理Controller之间的跳转;4、实现Controller容器。显然没有数据解析功能,所以就需要创建一个新的类来进行数据解析。
所以就创建了一个专门解析数据的类:ViewModel。
3. MVVM
View视图:用户界面
Model模型:对数据进行存取
ViewModel: 对数据的解析。
MVVM中的M,V和MVC中的M,V完全一样,VM就是数据解析的类,因为有数据解析VM存在,所以Controller的存在感就降低了。Controller现在是持有VM,而不是M,任何需要数据的时候Controller就会向VM去获取解析好的数据。
MVVM模式数据的传递:采用双向绑定,View的变动,自动反映在 ViewModel,反之亦然。