前言
最近一段时间在看斯坦福大学的iOS9视频课程,斯坦福老头在讲解MVC时我收获良多。参考Swift编程(四):深入浅出MVC模式一文,在观看完Applyiing MVC一节视频后,我也试着总结一下该节视频的关键知识点。
MVC设计模式
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。(来自百度百科)
MVC简介
从本质上来说,MVC模型将应用或代码分割成三个不同的“阵营”:
模型(Model)
The Model camp is what your application does.
Nothing about how it‘s drawn on screen or how it's displayed.
解释:模型是你的应用是什么,是程序的行为的合集。
视图(View)
The View, you can think of as your controller's minions.The things that the controller's gonna user to put things on sceen.
解释:视图是控制器的仆从,那些controller想要在屏幕上展示的界面控件,如UIButton、UILabel、UITableView等,用于展示Model的信息。
控制器(Controller)
The controller is how your model is displayed on screen.It's kind of the how.This is basically all your UI logic, goes into your controller.
解释:控制器是控制你的模型如何在界面上展示的工具。关键在于如何进行展示,控制器主要包含了你的界面逻辑以及界面的跳转。
MVC三个“阵营”运转的机制
三个“阵营”交互的关键在于,哪些行为是允许的,哪些行为是不允许的,以及什么时候进行交互,如何在iOS中实现,如何促进各“阵营”的交流。
MVC解释:
如图,斯坦福老头在中心绘制了一个’Y‘字的图案,在’Y‘的下方有两条黄色的线条,表示两边是不相通的,上方两条白色的线表示两边是可以相通的。
注意:三个“阵营”交互的方向总是固定的。
控制器(Controller)& 模型(Model)的通信
控制器(Controller)-> 模型(Model)
Controller知道Model所有的属性和方法,可以调用Model所有的方法。Controller能完全控制
Model,这是因为controller的任务就是展示给用户看Model的信息,或者从用户处获得信息以及更新Model的信息。
见上图,绿色箭头和白色虚线表示Controller可以完全控制
Model。
模型(Model)-> 控制器(Controller)
一般情况下,Model是不能与Controller通信的。为了实现Model如何通知Controller它的数据发生变化,iOS采用Notification(广播)
和KVO(键值对观察)
的形式。广播的机制是:Model将自己设立为广播中心,通过发送广播,通知那些对数据变化有监听的广播站,然后将Controller设置成接收广播的设备。由此可看出,Model并不会直接对Controller进行通知,它只是通知那些想知道的对象。
控制器(Controller)& 视图(View)的通信
控制器(Controller)-> 视图(View)
Controller希望展示Model的信息,需要使用到它的“仆从”(View)。大部分情况下,从Controller到View的交互方式都是通过Outlet
来实现的。
见上图,带有Outlet字眼的绿色箭头和白色虚线表示Controller可以完全控制
View。
视图(View)-> 控制器(Controller)
从View到Controller的通信的问题在于,所有的控件都是一个通用的类型,例如UIButton或UILabel,对于这些控件来说,它们不能真正地了解调用它们的Controller,故它们只能以盲目的方式与Controller通信。因此Controller与View之间的通信是有限制的。
-
Target-Action模式
只需通过Ctrl + 左键
拖拉控件到Controller,此时Controller被设定成target
,在Controller会生成一个返回类型为IBAction
的方法。当View向Controller通知有事件在它身上触发时,view根本不需要知道它通知的Controller是什么样的,只需简单地调用该方法即可,
见上图,带有action字眼的短小的黄色双箭头,一端黏在View上,一端大概地指向Controller。 -
delegate(委托)和 dataSource(数据源)协议
delegate(委托)
有些时候,发生在View上的事件比较复杂,通过Target-Action模式
无法通知给Controller足够的信息。如tableView的滚动、某一行被点击等,这时候view可以将Controller设置为它的delegate
,委托Controller来处理这些复杂的事件。通常这些委托方法的名字会带有will、should、did等关键字。
dataSource(数据源)协议
疑问:我们知道,任何View都不能包含它们所展示的Model,那么在没有Model的情况下,View是如何进行展示的?
解释:除了上面的delegate(委托)协议,还有另外一种协议——dataSource(数据源)协议。dataSource协议的方法不带will、should、did等关键字。借助这些dataSource协议方法,View通过询问Controller,而Controller从Model中获得数据,从而View可以获得需要显示的数据,以及根据数据来决定如何显示。
模型(Model)& 视图(View)的通信
Model和View是相互独立的,所以它们之间完全不可能产生直接交互。对于那些完全和界面独立的Model来说,View只是Controller的仆从,Model和View之间的交互是完全没有意义的,因此在实际设计中也不允许这样做。
网友评论