一、什么是MVC
单例、通知等是我们在项目中经常用到设计代码的一种方式,MVC和他们一样也是一种用来设计代码的模式,他就像一个模板,一个框架,我们这个以这个框架为模子,创造我们的代码。
二、MVC的分工
M(Model)
1、给ViewController存储数据、处理数据、提供数据
一般的我们在Model会有很多属性,这些属性就是用来保存数据的;
我们在Controller里面拿到这些属性就可以给View赋值,这就是Model给Controller提供数据,Controller将数据给View;
有时候Model中存储数据的时候需要对数据进行处理,比如数据需要转换成字符串存在属性里等,这都是在Model中做完,然后存储起来,这就是处理数据。
2、给ViewController提供接口
有很多小伙伴将Api接口直接写在Controller里面,拿到服务器请求到的数据后直接在Controller里面处理,处理完直接用,这样可以实现功能,但是请求多了、项目大了导致Controller里面各种代码,各种逻辑,慢慢就难以维护了。这样做其实是将Model的工作交给了Controller,Model的职能没有被做大的化的使用。
其实我们可以将Api写在Model里面,Model请求到服务器数据的时候在Model做完数据处理,然后直接返回给Controller,Controller拿到Model处理好的数据直接做其他刷新UI的操作这不是很有章法的吗,而且逻辑紧凑,分工明确。
3、提供经过抽象业务基本组件,供Controller调度
- 举个很简单的例子,大家项目里有没有用摄像头,或者定位等功能,我们把这些功能进行二次封装,封装成我们项目所需要的,更能给项目提供更加便捷的类。这些类我们大多数人把它叫做Manager,定位管理类,系统相册管理类...这些继承于NSObject的类被你改了个名字你就不知道它属于Model的吗?他们其实是一回事,都是Model,有些人可能会说照你这样说只要是继承NSObjct的类都是Model,我可以确切的告诉你:是的,没毛病。
V(View)
1、构成UI
- 注意点就不用说了,View上面有各种UI界面的东西。
2、响应UI事件
这里注意了,相应UI事件不是说相应事件的处理就在View中做,如果你这样做你可以试试看;
View的事件通过代理的形式告知Controller,Controller实现协议执行事件的代理,这时候在代理里面处理业务操作;
强调一点就是关于一些UI的动画,如果合适的话尽量放在View里面去做;
3、展示UI
- 也不用说,UI需要填充数据,展示UI。
C(Controller)
1、管理ViewController的生命周期
- Controller的周期函数
2、负责初始化所有UI的实例,并将其添加到self.view上
- 在Controller中将创建View并添加在self.view上,使得UI展示出来。
3、通过监听、代理等方式处理来自View与业务先关的事件,实现相关业务
- 在Controller实现View的代理或者监听,当View层有事件发生的时候就会委托Controller实现代理方法,在代理方法中处理好相关的业务。
4、通过与Model的交互,获取Model的数据,将数据给View
- Controller中通过Model发起网络请求,然后Model将网络请求来的数据处理好后返回给Controller,Controller在将这些数据给View,实现给View界面赋值或者刷新View数据。
三、 MVC的本质
1、Model就是一个继承自NSObject的类;
- 在MVC设计模式中,大多数人将Model看做是Controller的Model,其实它不仅仅可以作为Controller的Model,它也可以看做是view的Model,哪个view呢,就是Controller自带的self.view。在MVVM中View有自己的Model,在这里是同理。当然你可以在项目中将Controller的Model和View的Model分开,各自管理各自的Model,View的Model为View提供数据,Controller的Model为Controller提供api接口,视项目情况定,不深入学习和体会对view的Model和Controller的Model界限会很模糊。
2、View就不用说了;
3、重点来说一下Controller
Controller的组成:Controller大家都知道它是容器,那它为什么可以作为容器?
首先来看Controller的组成,从新建的Controller里面我们可以看出来Controller是由周期函数、一个View,即self.view组成,或者还有其他的,就不说了不是重点。
也就是说Controller上面是有一个View的,那为什么需要这个View呢,因为我们将创建的UI实例都放在这个View上,才能将UI展示出来。
这样一来就透彻了,Controller上有个View,我们将UI是放在这个View上才能展示出来的,Controller里面装了一些UI,与其说是Controller装了些UI还不如说,因为Controller上面有一个View,这个View里面装了一些UI的实例,所以才能展示出来UI层。
所以说View才是个容器,Controller如果没有自带的这个View它就不能被称作是容器。
所以说在iOS里面UIView不光可以用作是展示UI的对象,还可以作为容器的一个对象。
四、示例
这里有一个ViewController,ViewController里面有一个View,_userInfoView用来展示用户信息。ViewController中还有一个UserInfoModel用来存储和管理用户信息。
@interface ViewController ()
{
UserInfoView *_userInfoView;
}
/**
ViewController的Model
*/
@property (nonatomic, strong) UserInfoModel *infoModel;
@end
ViewController中周期函数:
#pragma mark cycle
- (void)viewDidLoad {
[super viewDidLoad];
//UI
[self setUpUI];
//request
[self requestUserInfo];
}
这里没写其他周期函数,看项目需要自行添加。在viewDidLoad里面一个方法是初始化UI,另一个方法请求服务端数据。
infoModel通过懒加载用的时候在创建。
在请求数据的方法中需要做很多处理和操作:
#pragma mark request
- (void)requestUserInfo {
//Code...
/*1、在这里通过self.infoModel调起一个方法;
2、通过此方法在self.infoModel中发起请求用户数据的网络请求;
3、请求返回后在self.infoModel中处理好数据,将数据保存在UserInfoModel中;
4、然后将结果用block或者代理的方式回调到ViewController中;
5、ViewController得到回调后,从self.infoModel拿到数据,然后赋值给_userInfoView;
6、_userInfoView通过赋值的方法将用户信息赋值在view上展示出来。
*/
}