用以分类程序中的所有目的到五个阵营中的任意一个,长远浅出MVC方式

写在前头:

欢迎大家关怀自我的个体博客:<a href=”http://blog.noasis.cn
>博客地址</a>,那里最重即使自身在民用开销时候蒙受的坑和挖完的坑,包罗PHP CentOS 以及 Swift 等有关只是

那是一篇纯理论的稿子,深远浅出的讲课一些本身在学习清华公开课时知道的MVC模型,它不用是唯有的翻译其中的始末,那是作者将他讲授的内容通过祥和明白过滤后一字字码出来的,具有很强的逻辑性,以便让咱们以及自身要好在此后更好的去精晓

MVC全名是Model View
Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法协会代码,将工作逻辑聚集到一个构件里面,在改正和个性化定制界面及用户交互的同时,不需求再一次编辑工作逻辑(来自百度周密)

MVC模型

前言

近日一段时间在看弗吉尼亚香槟分校高校的iOS9摄像课程,华盛顿圣路易斯分校老人在讲解MVC时自己获得广大。参考斯威夫特编程(四):深刻浅出MVC方式一文,在见到完Applyiing
MVC一节视频后,我也试着计算一下该节视频的最主要知识点。

简介

MVC是一个中坚模型,用于分类程序中的所有目标到两个阵营中的任意一个。

  1. 模型(Model)
    Model = What your application is (but not how it is displayed)

模型(Model),模型层是先后的行为的合集

  1. 视图(View)
    View = Your Controller’s minions

视图(View),视图层是控制器(Controller)的协理类,大家在创设我们的界面时会用到它,在视图(View)中的内容是一对一通用的界面元素

  1. 控制器(Controller)
    Controller = How your Model is presented to the user(UIlogic)

控制器(Controller),控制器(Controller)的成效给View解释并格式化这么些来源模型(Model)的多少

MVC设计形式

MVC全名是Model View
Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种工作逻辑、数据、界面呈现分离的格局协会代码,将事情逻辑聚集到一个构件里面,在革新和个性化定制界面及用户交互的同时,不须求再行编排工作逻辑。(来自百度宏观)

通信

毋庸置疑的MVC不仅仅知道内容的寄放地点而且亟需驾驭三层是如何通讯的,接下去大家总括一下那三层是何许通讯的。
(双黄线和反动虚线表示通讯形式)

MVC简介

从精神上的话,MVC模型将拔取或代码分割成四个不一样的“阵营”:

控制器与模型的通讯:

模型(Model)

The Model camp is what your application does.
Nothing about how it‘s drawn on screen or how it’s displayed.

分解:模型是你的采纳是怎么着,是先后的一言一行的合集。

1. 控制器(Controller) -> 模型(Model):完全控制权

Controller可以驾驭Model的所有行为,并且必须完全有能力与Model通讯,根据Controller的须要使用Model公开的接口(API),因为Controller的职务就是通过View想用户显示Model中的数据,由此Controller拥有完全控制权限可以与Model通讯。

视图(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的信息。

2. 模型(Model) -> 控制器(Controller):Notification(文告)和KVO(键值对考察)

常见情况下,Model是不可以与Controller通讯。
情景:Model中的数据爆发了变更,而Controller须求知道那种变化,如:数据变动了,数据库改变了。
题材:Model怎么着与Controller通讯告诉她这几个生成?
答案:Model会用一种电台的定义,将音讯播报给想了解的别样Controller,在IOS中这种技术叫做Notification(布告)和KVO(键值对考察),所以Model的义务就是当数码发生变化是,通过Notification(文告)和KVO(键值对考察)广播一下,随后Controller会接收到来自广播的音讯,他会发觉数目在转移,他会再与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中贯彻,怎么样推进各“阵营”的沟通。

图片 1

MVC

解释:
如图,俄亥俄州立老人在中央绘制了一个’Y‘字的美术,在’Y‘的人间有两条黑色的线条,表示两边是不相通的,上方两条白色的线意味着两边是足以相通的。
在意:八个“阵营”交互的大方向连接永恒的。

1. 控制器 -> 视图:完全控制权

Controller是可以访问View的,因为控制器负责通过我对象向View发送指令,View是Controller向用户体现界面的一种办法,因而Controller可以操纵View做任何它想做的事,那里会提到Outlet的概念(Outlet是控制器的一个性质,用于指向视图)。大家创立一个Outlet实际上就是实例化一个View到Controller中,那样大家的Controller可以发送指令到对应View了
<pre>“`swift
class DemoViewController: UIViewController {
@IBOutlet weak var table: UITableView!
}

如上代码:UITableView作为一个视图,table即Outlet(DemoViewController的一个指向UITableView的属性),这样DemoViewController就具有了对UITableView的控制权了


 ####2. 视图 -> 控制器:代理(Delegate)和数据源(DataSource)
>因为View是通用的,他们不能真正的了解调用它们的Controller,所以他们只能盲目的方式与Controller通信
问题:视图上有个按钮(UIButton)它能跟Controller通信吗?
答案:可以,但是要注意,因为View是通用的,他们不能真正的了解调用它们的Controller,所以他们只能盲目的方式与Controller通信。一种大家都认同的,View与Controller通信的方式(Target操作和代理)

 >#####方式一: addTarget操作

 >控制器(Controller)本身写一个目标方法(target),然后给View的行为方法(action),并告诉View当你想做执行操作(比如你是一个按钮被点击,或者滑动条被滑动)给控制器(Controller),你可以通过此行为方法(action)向Controller发送消息,通过这种方式,通用的按钮或者拖动条就可以反过来与Controller通信了,它根本不需要知道调用的它控制器到底是什么类型的Controller,他只需要知道某一个事件在他身上触发时他就要通过行为方法(action)想目标方法(target)发送一个消息,就是这样一个盲目的、简单的、结构化的方式来作为视图与控制器之间的通信。还是代码比较直观`(*∩_∩*)′

 ><pre>```swift
    class DemoViewController: UIViewController {
        @IBOutlet weak var btn: UIButton!
        override func viewDidLoad() {
            btn.addTarget(self, action: "hello:", forControlEvents: .TouchUpInside)
        }
        func hello() {
            print("Hello World!"
        }
    }
```</pre>

 >这样是不是很好理解:在DemoViewController中添加一个target:hello(),然后通过addTarget给View对象btn添加action。当你点击按钮时,就是打印:Hello World!

 > #####方式二:代理(Delegate)和数据源(DataSource)

 >代理(Delegate):
>假如有时发生在视图(View)上的事件是比较复杂的,理解这个的方法是我通过几个关键字(will、should、did)描述这些情况:
>- 假如我们的View是一个滚动视图(ScrollView),用户按住它,将要滑动,它想要Controller知道用户将要执行滑动操作(will)
 >- 假如它正在滚动,并且它想让Controller知道用户刚刚做了滚动操作(did)
>- 又或者用户按住屏幕滚动视图(ScrollView)需要知道是否允许这里执行滚动操作(should)

>所有这些情况,滚动视图(ScrollView)本身或许没有足够的逻辑知道那些问题的答案,那它需要做的就是代理给Controller对象来回答这些问题(will,should,did,this,that或者其他事情例如:允许滑动、滑动到一点等等等...),你将要在那些代理协议中看到他们。这里我们需要在控制器中代理这些协议(盲目通信)
依旧是代码才会有更好的直观性,还记得在我们<a href="http://www.jianshu.com/p/150ba0779cc0">文章(一)</a>和<a href="http://www.jianshu.com/p/f5cc032e74f5">文章(二)</a>需要给UITableView做代理吗?其实我介绍了两种方式,我更偏向第二种:拓展方式,代码逻辑更清晰

><pre>```swift
extension DemoViewController: UITableViewDelegate {
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
    {
        let index = indexPath.row
        let string = self.dataList[index]
        if let closure = self.myClosure {
            closure(tag: self.myTag!,string: string)
        }
        self.dismissViewControllerAnimated(true, completion: nil)
    }
}
```</pre>
上述代码:控制器:DemoViewController代理了视图UITableView的didSelectRowAtIndexPath协议,告诉视图我选中了某一行时需要执行的操作。

>数据源(DataSource):
视图(View)不应该持有展示他们的数据,如果持有数据就违背了视图(View)的通用性了,换句话说:数据不应该作为视图的内部属性。
场景: 例如你要展示iPhone上的所有歌曲,你可能有10000首歌曲,另外你有一些通用的视图列表在你的视图(View)中,你不能传递这10000首歌给他实例变量中,并期望它来持有10000首歌以便你去浏览他们。
原因:
 - 这种方式不高效;
 - 这10000首歌属于哪一层?应该是Model。

>你的音乐数据库本身就是一个Model(它与UI无关),视图仅仅是歌曲、艺术家、专辑和其他信息的一个列表 ,Controller必须通过Model查询数据并告诉一个View如何展示这些歌曲,所以我们需要通信让View展示数据,这些通信如何发生?答案:使用另一个种特殊的代理——数据源(DataSource),数据源不做之前代理(will、should、did……)的事。数据源(DataSource)做类似:数量:(有多少首歌曲),Controller查找Model将10000返回给视图,然后视图(View)为这些歌曲开辟内部空间。
当你在底部滚动它,他就开始发消息给控制器加载10条记录(返回150行后面的10条数据),控制器再次跟Model通信,并获取接下来的10条数据,于是控制器(Controller)通过这种盲目方式提供数据给视图,这就是视图(View)如何通过Model得到数据是通过这种不明确的、没有针对性的、结构化的方式。
所以数据源(DataSource)就是一个特殊类型的用于获取数据的代理,像列表视图(UITableView)他就有一个数据源和一个通常的代理
依旧是代码:上面我们给UITableView做了代理,接下来我们为UITableView绑定数据源

><pre>```swift
extension DemoViewController: UITableViewDataSource {
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.dataList.count
    }
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier(self.cellId, forIndexPath: indexPath) as! DemoListCell
        //cell.cellImg.image = UIImage(named: powerData[indexPath.row][2])
        cell.cellLabel.text = self.dataList[indexPath.row]
        return cell
    }
}
```</pre>

总结:OK!这就是View: UITableView跟控制器(Controller)的通过一种不明确的结构化方式:分为代理(Delegate)和数据源(DataSource)


### 模型与视图的通信:不能(Never)
 - 很明显,模型(Model)是完全独立于UI的,模型没有任何办法向视图对象发送只送指令,也不能和视图层的任何对象通信,因为视图对象是基本的UI对象,他们是某种程度上是通用的,但是也是基本的UI对象,既然视图对象是通用的对象,他们就不能和任何特定的Model对象通信,他们需要一个控制器来传达信息。一句话:模型(Model)与视图(View)之间在没有任何通信




## 重要体会:
最后你会体会到,IOS开发框架本就是MVC模式,我们常用的控件无一不是视图,我们创建的ViewController其实都是控制器,我们实例化一个控件,就是为我们的Controller创建一个Outlet,并对其显示和控制,说到Model,CoreData就是我们的Model,原来我们一直都在MVC的世界里摸索到底什么才是MVC,多么痛的领悟!

## 名词解释:
 - M(Model):模型
 - V(View):视图
 - C(Controller):控制器
 - Outlet :控制器指向视图的属性
 - Notification:通知
 - KVO(Key-Value Observing):键值对观察
 - Delegate:代理,视图向控制器通信,通过 will、should、did等方式统称为代理
 - DataSource:数据源,一种特殊类型的代理,取决于视图是否需要显示大量数据
 - protocol:协议,在编程中含义:我的理解通过一种盲目(Blind)的、没有针对性的方式与其他对象通信。

![多个MVC](http://upload-images.jianshu.io/upload_images/796183-b0d7975f137479cc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

如果是一个比较大型的复杂的项目呢?在屏幕上有三四个不同的区域都在发生着什么,我们可以结合多个MVC

控制器(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之间的交互是截然没有意义的,因而在事实上设计中也分化意那样做。

参照链接

斯威夫特编程(四):长远浅出MVC情势

被误会的 MVC 和被神化的
MVVM

Developing-iOS-9-Apps-with-Swift-lecture2.Applying
MVC