iOS中MVC设计模式

一、什么是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上展示出来。
     */
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容