MVC,了解模型的观点

时间:2012-07-26 18:28:37

标签: iphone model-view-controller

这可能是一个愚蠢的问题,但在MVC中,视图并不知道模型的正确性。我查看了表视图单元格的一些示例,表格视图单元格具有模型对象的属性。然后,它使用该模型的属性来填充标签或单元格的图像。

或者在另一种情况下,如果我有一个基于模型动态绘制内容的UIView,看起来在UIView上拥有一个属性是最容易的,所以UIView可以访问该模型的数据以便绘制它动态。所以我可以这样做:

myView.object = newObject;
[myView setNeedsDisplay];

这对MVC有误吗?如果是这样,做这两件事的更好方法是什么?感谢。

3 个答案:

答案 0 :(得分:4)

MVC模型有不同的变体--Cocoa的Apple文档在这里:http://developer.apple.com/library/mac/documentation/General/Conceptual/CocoaEncyclopedia/Model-View-Controller/Model-View-Controller.html#//apple_ref/doc/uid/TP40010810-CH14-SW9

我从中获取的主要内容是视图不应直接链接到模型。请参阅此图:

Apple diagram of Cocoa MVC pattern

您提到UITableViewCells通常具有模型对象的属性 - 我建议这是错误的。模式应如下:

  • 模型处理所有实际数据存储和管理
  • 查看知道正在显示的数据的类型,但不知道数据本身。
  • 控制器(UITableViewController)是从模型中获取数据并设置视图的“粘合剂”

这在实践中如何运作?

请原谅以下psuedo代码中的一些错误,因为我直接输入了它,我没有测试过任何错误,但希望它能说明这一点。

所以你有一个UITableViewCell子类,如下所示:

@interface PhoneEntryTableViewCell {

@property (weak) IBOutlet UILabel *personName;
@property (weak) IBOutlet UILabel *phoneNumber;

}

模型如下所示:

@interface PhoneModel {

@property (strong) NSMutableArray *listOfPeople;

}

UITableViewController实施标准UITableViewDelegate / UITableViewDataSource方法,例如:

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath {

  Person *person = [myModel personForIndex:indexPath.row];

  PhoneEntryTableViewCell *cell = [self dequeueReusableCellWithIdentifier:@"PhoneCell"];
  cell.personName.text = [person name];
  cell.phoneNumber.text = [person phoneNumber];

  return cell;
}

总而言之,查看对实际数据一无所知 - 它只知道必须显示一个人的姓名和电话号码。它不知道后端存储是什么 - 它可能是核心数据,文件,下载和解析的JSON等。它对模型一无所知 - 例如,也许它存储关于Person的其他数据,也许电话号码实际上存储在与名称不同的模型中。 控制器处理所有这些工作。

为什么会这样?

因此,您推出上述应用程序,然后发现您的模型非常慢 - 您可以将其换成完全不同的模型,而无需触及查看。也许你可以让其他开发人员或设计师创建查看 - 他们需要知道的是它必须显示两位文本。基本上它允许您的代码清晰,分区清晰,易于扩展,更容易重构。

现在,只要您在UITableViewCell视图中执行此类操作,所有这一切就会消失:

@property (strong) Person *person;

答案 1 :(得分:0)

首先:没有“MVC模型”。它以不同的方式概述,具有微妙但重要的差异。

如果视图中的组件需要获取信息,则可以通过两种方式获取信息:询问(轮询)或收到通知(推送)。在大多数情况下,通知应该是更清晰的方法,因为视图实际上对模型一无所知,它只是作为observer

但是,GUI组件往往需要“模型对象”来保存数据,并且可以像您的示例一样询问它。尽管它们通常以模型命名,但在架构上它们并不需要属于它。在我看来,它们不应该,因为模型的接口是在预定义的GUI组件的需求之后构建的,并且整个MVC的感觉消失了。如果你想在模型和视图之间进行清晰的分离,你应该尝试这样的事情:

-----------------       -----------------       --------------      ---------
| GUI Component | --->  | "Model Class" | <-->  | Controller | ---> | Model |
-----------------       -----------------       --------------      ---------

因此,GUI组件所期望的“Model Class”对象只不过是控制器的适配器。在GUI和Controller之间的这种关系中,您现在可以实现您喜欢的任何策略 - 轮询或推送(双向箭头的原因)。

答案 2 :(得分:0)

  

或者在另一种情况下,如果我有一个动态绘制内容的UIView   基于该模型,似乎最容易拥有一个   UIView上的属性,以便UIView可以访问该模型的数据   为了动态绘制它。

那么为了获得正确的信息,你会对模型说什么呢?为了问正确的问题,它必须知道模型的某些内容,对吧?或者,您可以定义UITableViewDataSource之类的协议并发送-cellForRowAtIndexPath:之类的通用消息,然后在模型中实现该协议。这避免了视图需要知道关于模型的任何具体内容,但这意味着模型现在必须知道视图 - 它必须知道应该在视图中显示的内容以便它可以通过支持正确的数据。无论你采用哪种方式,你都会在模型和视图之间引入依赖关系,这意味着当你在一个模型和视图中进行更改时,你必须在另一个模型中进行更改。

避免这些类型的依赖关系正是MVC架构的重点。控制器知道模型和视图,它允许模型和视图彼此独立存在。

有时可能会有一些模型和视图都知道的对象。如果您正在编写地址簿,那么拥有一个知道如何显示联系人的ContactView以及一个存储Contact对象的模型可能是有意义的。这似乎比一个对它显示的内容完全愚蠢的观点更明智,它让你传递Contact对象,而不是很长的名单,地址,电话,传真,电子邮件等等。你可以说一个联系人是模型对象,以上所有内容都适用:您将在ContactView和Contact之间引入依赖关系。但通常当我们谈论“模型”时,我们指的是程序用来存储数据的整个对象图,而MVC的好处是将管理所有这些对象的方式与呈现数据的方式分开。它们包含。