首页 » iOS编程基础:Swift、Xcode和Cocoa入门指南 » iOS编程基础:Swift、Xcode和Cocoa入门指南全文在线阅读

《iOS编程基础:Swift、Xcode和Cocoa入门指南》13.5 模型-视图-控制器

关灯直达底部

Apple的文档和其他地方都会提及术语:模型-视图-控制器(简称为MVC)。这指的是一种架构目标,对于带有图形用户界面的程序(用户可以查看和编辑信息)来说,这个目标旨在实现程序在3个功能性方面的分离。MVC的概念可以追溯到Smalltalk的年代,从那以后关于它的介绍已经不胜枚举,下面是对这3个术语的通俗解释:

模型

数据及对数据的管理,通常称为程序的“业务逻辑”,程序真正关注的核心部分。

视图

用户看到并与之交互的部分。

控制器

介于模型与视图中间的协调部分。

考虑一个游戏,当前的分数显示在用户眼前:

·向用户展示当前游戏分数的UILabel是个视图;它只不过是个显示而已,其业务知道如何绘制自身。它应该绘制什么(即分数)取决于其他地方。

新手程序员会将UILabel所显示的分数作为实际的分数:为了增加分数,他会读取UILabel上的字符串、将其转换为数字、增加该数字、将数字转换回字符串,然后用该字符串替换掉之前的字符串。这完全违背了MVC哲学!呈现给用户的视图应该反映出分数,但不应该存储分数。

·分数是个内部维护的数据;它是个模型。它可能会像拥有公开的increment方法的实例属性那么简单,也可能像拥有大量方法的Score对象那么复杂。

分数是个数字,而UILabel显示的是个字符串;这足以表明视图与控制器本质上是不同的。

·告诉分数何时应该变化,并在用户界面上显示出更新后的分数,这是控制器的职责。模型的数字分数会通过某种方式进行转换以显示给用户,如果这么想就很清晰了。

比如,假设UILabel显示的分数内容是“The score is 20.”。模型会存储并提供数字20,那么短语“The score is...”来自于何处呢?控制器会将这个短语放到数字前并呈现给用户。

这个简单的示例(如图13-1所示)能够很好地说明MVC的优势。通过这种方式进行分离,程序的不同部分可以在很大程度上独自演化。需要使用不同的字体与大小展现分数吗?修改视图即可;模型与控制器不需要知道这些,只是按照之前那样工作即可。想要修改分数前的短语吗?修改控制器即可;模型与视图不会发生任何变化。

图13-1:模型-视图-控制器

在Cocoa应用中遵循MVC尤为重要,因为Cocoa本身就遵循了MVC。Cocoa类的名字揭示出了底层的MVC哲学。UIView是个视图;UIViewController是个控制器;其目的体现出了视图应该显示什么的逻辑。第11章我们看到一个UIPickerView并没有持有所要显示的数据;它是从数据源获得数据的。因此,UIPickerView是个视图;由数据源所维护的数据则是个模型。

Apple的文档是这样表述的:真正的模型与真正的视图应该是可重用的,它们可以迁移到其他应用中;控制器一般来说是不可重用的,因为它关注的是如何协调模型与视图。

在我开发的一个应用中,我会下载一个XML(RSS)新闻种子并以表格形式将文章标题展现给用户。XML的存储与解析完全是模型的事情,因此是可重用的,我甚至都没有编写这部分代码(使用了Kevin Ballard编写的名为FeedParser的代码)。表格是个UITableView,它显然是可重用的,因为它来自于Cocoa。不过,当UITableView转向我的代码并询问应该在单元格中显示什么时,我的代码会转向XML并请求与表格的这一行相对应的文章标题,这是控制器代码,它只适用于这个应用。

MVC为应用中对象之间的可见性提供了答案。控制器对象通常要能看到模型对象与视图对象。模型对象或模型对象组通常不需要看到外面。视图对象通常不需要看到外面,不过诸如单例、数据源与目标-动作等结构化设置可以让视图对象与控制器通信。