您的位置:首页 > 移动开发 > IOS开发

iOS 之 MVC 开发模式 经典篇

2014-11-22 09:15 260 查看
从字面意思来理解, Modal , View , Controller ,其用意在于将数据与视图分离开来。 在iOS cocoa touch 编程中, MVC机制被发挥得淋漓尽致。 MVC 示意图如下。 只有充分理解了MVC,才能在编写出优雅的iOS app。为充分理解 MVC, 相关的概念(比如: Delegate、 Protocol、 Notification 等)也要了然于胸。

MVC 约定, Model 不允许与View 打交道。 Model 是管理数据的, 当Model中的数据发生变化时,与之对应的视图应更新。 这就需要一种机制来支持。为此 iOS 框架提供了两种支持机制: Notification 和KVO (Key-Value Observing)。 KVO 可简单理解为,为你所关注的 Key 对象注册一个监听器。 当有数据发生变化时,就会发出广播给所有的监听器。
MVC 也约定, View 不允许直接引用Modal, 它只能被Controller 所控制。 Controller 控制 View 显示什么数据。我们知道,View 所要显示的数据是来源于 Modal, View 上产生的事件 ( 比如 Touch事件)需要通知 Controller。 既然MVC 不允许直接打交道,就需要提供一种机制。
不错, iOS 确实提供了一种机制, 名曰: Delegate。 Delegate 这个词, 有人将它译为“委托”,也有人将它译为“代理”。名称上的差异没有什么,重要的是如何理解 Delegate。 Delegate设计模式的引入,就是为了解决UIView与Controller松耦合互动问题。

为便于理解, 这里截取一张来iOS MVC 示意图:



iOS 有三种常见的模式:

设置View对应的Action Target。如设置UIButton的Touch up inside的Action Target。
设置View的Delegate,如UIAlertViewDelegate, UIActionSheetDelegate,UITextFieldDelegate等。
设置View的data source, 如UITableViewDataSource。
通过以上三种模式,View既能向Controller通信,又无需知道具体的Controller是谁,这样,View 就与Controller解耦了。
除此之外, iOS 还提供了 Action-Target 模式来让Controller 监听View 触发的事件。 View 又是如何获取数据呢? iOS提供了 Data source 的概念,其实也就是Protocol 的应用。



图中有几条线把这三部分划分开,有黄线,虚线,和白色的实线。我们把它们想象成路标。你可以看到,在M和V之间有两条黄线,这表示什么呢?它意味着你不能穿越这黄线,任何一个方向都不行。在图的上部,你可以看到白色的虚线,它意味着你可以自由的穿越它,只要是安全的。那白色的实线呢?它代表你可以穿越,但你必须要买票,或者交点过路费。 好了,如果你觉得前面的比喻没有使你明白的话,让我们来讲点实在的东西。 首先, 我们来看C和M之间的绿色箭头,这箭头的方向就代表着“发起对话”的方向,也就是说,发起对话的是C,而做出回答的是M。C可以问M各种各样的问题,但M只是回答C的问题或要求,它不可以主动的向C要求什么。还记得虚线是畅通无阻的意思吧,所以,C知道M的所有的事情,如果用代码来说明这件事情,就是说,C可以导入M的头文件或是M的接口(API)。因为C可以通过M的API,所以它就可以肆无忌惮的向M要求这要求那了。 我们再来看看另外的一个绿色箭头,它是在C和V之间,和前一个绿色箭头的意义一样,它代表C可以直接地向V进行交流。你可以想想,C要把V放到屏幕上,并设置V的属性,告诉它们什么时候从屏幕上消失,把它们分成组等等。如果C不能自由的向V发号施令的话,程序的显示将会多么的困难,所以,C可以毫无限制地向V说话。 可能你已经注意到了,这个箭头上还有outlet(输出口),outlet可以看作是从C指向V的指针,它在C中被定义。outlet给我们提供了很大的方便,它使我们在C的内部就可以轻松准确地向V施令。C可以拥有很多的outlet,可以不止一个,这也使它可以更高效的和V进行交流。 那M和V之间可以交流么?还记得黄线的意思么?完全不可以通过,所以我们是不允许M和V进行交流的。这是因为我们不希望这三部分之间有过多的交流,你想想,假如V在显示时出现了问题,比如有一个图形没有显示出来,我们就要去查找错误,因为C可以和V交流,M也可以和V交流的话,我们就要去检查两个部分。相反的,只有C可以和V交流的话,在出错时,我们就只需要去C那里查找原因,这样查找错误不就很是简单了么?所以,我们不允许M和V之间有直接的联系,这也是在它们两之间有两根黄线的原因。 好的应用程序要具备与用户交互的能力。如果没有良好的交互性,程序的功能将会受到很大的限制。在MVC中,V是和用户直接接触的,用户看不到M和C,所以,程序与用户的交互必须通过V来实现,但V只是视图而已,它并不能完全处理用户的要求,所以,这就要求V必须有某种手段来向C发送信息,移交用户的交互要求。这手段就是前面白色实线代表的过路费,你知道V不能知道C的一切,但它可以通过某种“手段”来和C进行交流,移交用户交互责任。 我们接下来讨论V是如何向C发送信息的。V对C的交流有三种不同的方式。 第一种我们称为目标操作(target-action)。它是这样工作的,C会在自己的内部“悬挂”一个目标(target),如图中的红白相间的靶子,对应的,它还会分发一个操作(action,如图中的***箭头)给将要和它交流的视图对象(可能是屏幕上的一个按钮),当按钮被按时,action就会被发送给与之对应的target,这样V就可以和C交流了。但是在这种情况下,V只是知道发送action给对应的target,它并不知道C中的类,也不知道它到底发送了什么。target-action是我们经常使用的方法。 第二种方式我们叫做委托(delegate)。有时候,V需要和C进行同步,你知道,用户交互不仅仅是什么按按钮,划滑块,还有很多种形式。好了,让我们来看看图中的delegate***箭头,你发现箭头上又分出了四个小箭头:should,did,will,还有一个没标注的。绝大部分的delegate信息都是should,will,did这三种形式。和英文意思相对应,should代表视图对象将询问C中的某个对象“我应该这么做么?”,举个例子,有一个web视图,有人点击了一个链接,web视图就要问“我应该打开这个链接么?这样做安全么?”。这就是should信息。那will和did呢?will就是“我将要做这件事了”,did就是“我已经做了这件事”。C把自己设置为V的委托(delegate),它让V知道:如果V想知道更多的关于将如何显示的信息的话,就向C发送delegate信息。通过接受V发过来的delegate信息,C就会做出相应的协调和处理。还有一点,每个V只能有一个delegate。 第三种方式就是数据源(datasource),你知道,V不能拥有它所要显示的数据,记住这点非常重要。V希望别人帮助它管理将要显示的数据,当它需要数据时,它就会请求别人的帮助,把需要的数据给它。再者,iphone的屏幕很小,它不能显示包含大量信息的视图。看图中的datasource箭头,和delegate类似,V会发送cout,data at信息给C来请求数据。 好了,这就是V给C发送信息的三种形式。 最后一个问题。你看到M和C之间的白线,这意味着M不可以直接地,没有限制的对C进行交流。但有时,这个方向的交流是必要的。当M中的一些东西发生变化时,C需要了解这些变化,那我们怎么才能让C知道M的变化呢?通知(Notification)和KVO是解决问题的好方法。它们是这样工作的,当M中的某些东西发生变化时,他们会向C发出通知“嘿,老兄,注意了啊,我这发生变化了”,或者他们会发出指向变化的指针给C,或其他什么的。总之,他们的工作模式是这样的。 下面是我们的一个总结,cocoa忠实于MVC,所以理解cocoa的MVC是我们关键的开始,希望这些能使你明白一些。 C对M:API
C对V:Outlet
V对C:Target-action, Delegate,Datasource
M对C:Notification,KVO转自:http://wangwenhao.net/2011/10/20/mvc-in-ios/http://hi.baidu.com/janins/blog/item/1828a9f82f90509bb901a0d0.html?相信说起MVC(Model-View-Controller)大家都很熟悉。在iOS开发中MVC的机制被使用的淋漓尽致,并且我觉得在iOS上写程序,充分理解iOS的MVC模式,有助于我们程序的组织合理性,相反,我们不遵守MVC的一些约定,程序是可以写的,但就等着受苦了。下面我只对一些约定列一个表,并且说一下iOS的支持机制啊,算分享给大家:1、Model不允许和Controller,View打交道。也就是Model根本不知道谁会用自己,Model中不能有任何对Controller和View的引用。正所谓:Don't call me, I will call you.就是给Model设计说的。我们再想想,在一般程序中Model到处被拿去用,它要维护到底谁用真的很难。那你会问:兄弟,那当Model的数据变了,我怎么通知视图更新呢?这里常用的机制就是广播模式,或者电台模式,或者事件机制都行。在iOS中有两种支持机制:Notification和KVO(Key-Value Observing)。这两种东西原理差不多,KVO是iOS中的一个核心概念,简单理解就是:关注Model某个数据(Key)的对象可以注册为监听器,一旦Model某个Key的Value发生变化,就会广播给所有的监听器。这和Flex,JavaFX中的绑定都是一个道理。2、View不允许直接引用Controller和Model,它很专一地被Controller控制来进行数据的显示和接收用户的交互。我们知道View显示的时候需要数据,我们也知道在View上会产生事件。如果要达到不和Controller,Model直接打交道,就需要机制来支持。在Objective-C中有Protocol的东西,并且提出Delegate(代理模式)就是来解决UIView想和Controller松耦合互动问题的。除了这个外,iOS还提供了Action-Target模式来让Controller监听View的事件。那对View如何获得数据,iOS中提了Data Source的概念,其实也是Protocol的应用。3、每一次推给用户的一个操作屏幕,最好都是MVC的三者组合,不要出现一组以上的MVC组合。

转自:http://www.cnblogs.com/pengyingh/articles/2495376.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: