Something about MVC

MVC的主要宗旨是把所有的对象分为三个阵营,model阵营、view阵营和controller阵营
----那这些阵营是干什么的?

1

一、model阵营是你的应用是做什么的( Model = What your application is (but not how it is displayed))
举个例子:你在做一个人的模型,这个人的身高,体重,性别 就是 model,这些都是“这个程序是什么”的一部分,这就是model。我并没有说关于这个人的相貌、衣着,这些和model没有关系,那是view和controller干的事。

二、controller:你可以认为是你的model如何展现在用户面前(Controller = How your Model is presented to the user (UI logic))
它获取了这个人的身高等并将这些计算出怎么在屏幕上展现出来。这就是controller,controller 控制如何在UI上展现model。

三、view 是 controller 的仆人,view 就是controller使用的工具(View = Your Controller’s minions)
我们尽可能的使view阵营里的对象通用化,就像按钮、滑动条,这些都是苹果自带的。
view绝对不包含任何有关于如何去表现应用。
controller 利用这些通用view来做model需要做的事情。
view应该是很通用的,这很重要。因为系统上有很多view,还有和应用相关的功能来控制view,所以我们要更先进一点,利用通用的view来理解和使用这些功能。

四、一旦你有了三个阵营,剩下的就是他们之间的管理和通信问题
接下来我要谈一下哪些通信是被允许的,还有如何去完成

  • 让我们聊一下controller是怎样向model发消息的:

        controller向model发消息是100%被允许的(Controllers can always talk directly to their Model)
        controller可以问model任何问题,controller知道model的任何事情
        因为controller就是用来把model展现在屏幕上的,所以他要有完全的访问权
        这个箭头是单向的,所以只有controller知道model
        这里画的像一个交通标志,从controller到model是白色虚线,所以可以随时跨过去
    
2
  • 那么controller和view通信会是怎么样呢?

        controller是要把model显示在屏幕上,所以他可以对view做任何事(Controllers can also talk directly to their View)
        例如设个标志,让view做些东西,在屏幕上排列view,数据通信
        看见单词outlet,outlet是一个表达式,用来表示controller的用来和view通信的一个属性
        所以我们要在controller里创建outlets传到view中去
    
3
  • 那么model和view是怎样的呢?

        它们永远不会相互通信(The Model and View should never speak to each other)
        我相信你们都理解为什么model不和view通信,因为model和用户交互界面无关
        model是完全UI独立的
    
4

有些人会说,我有一些自定义view,掌控着model,所以能够显示model。这听起来挺吸引人的,但这不是个好主意的原因—重用。因为你把view和model连在了一起,model变了以后view要重写,view不能被重复利用,model也不能被其他UI用。比如iPad出来了,因为屏幕大小原因需要一个新的UI,你就得要重写整个view。
最好是把这部分放到controller里,建一些更通用的view对象。另一个原因是,如果view和model通信,那么现在所有人能和model通信了,view在和model通信,controller在和model通信,model就有点hold不住了。如果只有controller在和model通信就能容易很多搞清楚程序在干什么,把view排除在外,view只是controller的仆人,让controller来通信。

  • view能否允许和controller通信?
5

答案是某种程度上是可以的,view(通用的)和 controller(详细控制如何在屏幕展现model)之间的通信是不可见的,view不知道自己在和谁说话。但有一个好的架构,所以Xcode里我们有组织的连接view和它的controller。
所以,view向controller通信的方法,有结构的方法,一个被称为target action。target action很简单,就是controller自己画了一个target,然后把一个action交给他的view,当view发生了一些事情,比如按钮被按滑动条移动,它会把action发到target,然后controller就知道按钮被按了。这就是view向controller通信的机制,view回报controller发生了什么。但是view对controller知道的并不多,只是简单的发送target action。
事实上,还有view和controller之间比较复杂的通信,比如,view要和controller保持同步,所以常常view要告诉controller发生了什么,这是图上的did;或者将要发生什么,这是will;或者要问controller我是否允许什么发生,这是should。所以这些will、did、should是view要问的问题,这么做的原因是controller把自己设为委托(The Controller sets itself as the View’s delegate)。

 用协议,设立一个协议,来回应will,did,should。
 再一次,view不用知道回应的controller是哪一个类,delegation是另一个view和controller通信的方法。

 另一个重要的事是,view不是它显示的数据的所有者  ( View do not own the data they display),你们要了解view不拥有数据,view只是一个平面,用来显示数据,一个显示信息的平台。view没有实体变量也不会去存储,只有指向他们的指针。比如你iPod库里的1000首歌不会是view的实体变     量,这种设计使得,比如view不会去管理数据库,更新iPod歌曲库。这不是view的活,而是controller或者model干的。

 但如果view不拥有它所显示的数据,它如何获取数据呢?
 一个类似delegation的方法,他有一些协议,比如这里的data at 和 count 方法。这对一个表挺有用的,表可以去问表里有多少东西 ,比如5000,那好我要在第100到第150条数据,我要用来显示。view根据需求去请求数据,这会非常高效的,如果另外一头知道怎么管理一个巨大的数据库,而只提取其中需要的几条,因为你iPod里有1000首歌,但屏幕上一次只显示7条。你要这种功能,但不要把他写在一个view里,view是通用的用来显示的,controller和model一起来有效率的提供信息。
 类似的,view会有一个数据源的设置,controller会回应数据源(Controllers are almost always that data source (not Model ! )),注意,数据源的delegation永远是controller,或者是controller指定的第三方,但不可能是model,controller的工作是把model的信息传达给view,相应所有的delegation。因为它能获取model里的数据,决定怎么在屏幕上显示,这是他的职能,所以他要参与这个循环。
 你们可能需要这些data at 和 count 方法,可能只是一行代码,问model数据是什么,然后model把数据给你。即使只是一行代码,也需要controller来参与,因为这是controller的工作,获取model显示在屏幕上。

 上文重复了5遍“这是controller的工作”,因为这在iOS中很重要,你要给它机会做他的工作。
  永远不要超过view和model之间的线。

五、还有一件事,model能向controller发话吗?
这个很明显,肯定不行的。model是UI独立的,不能向controller发话,这是controller的工作来用view显示model。那么当model的一些东西改变了,你需要更新controller的时候该怎么办呢?假设你有个数据库,某人在数据库里写了某些东西,然后比如那个人的模型的属性被外界的事物改变了,现在model改变了是因为人变胖了。
在iOS里我们实现的东西是用一个广播站就像信息广播机制,有2个机制,通知和关键数据监听。当model改变了,他就在广播站广播,然后controller接收到了,去model里把什么东西改了。这个过程是无形的,也是同时的。
这就是Notification & KVO。这里的kvo也可以用于view和controller,但不会是view和model,view不会有面向model的广播,view和controller会相互有广播。
model广播非常好用,因为是不可见的,所以存在限制,只能通过被允许通信的对象发生了什么事。

六、MVC群
现在我们有了各个阵营所有的通信机制,我们要建一个复杂应用。复杂应用不仅仅只有一个controller、view,它会拥有几十个controller和view。比如登陆界面,点击了什么出来了一个表,再点一下表出来个其他什么的。各种各样的view被controller管理着,那要怎么做复杂应用呢?
答案是把MVC组成MVC群。

七、controller能否可以和其他人的view对话?
通常controller只会有个指针只想另外一个controller来当做view,它会根据那个controller来显示东西。controller的工作就是获取信息,显示信息。当controller需要显示复杂的东西时,他需要其他的controller。

 一个view只有一个与其搭配的controller。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容