4

我是一名新开发人员,正在创建一个简单的“字典”应用程序供个人使用,我的问题是如何在我的特定情况下正确实现模型-视图-控制器设计。请耐心等待我的必要背景:

我希望能够点击一个按钮并让一个标签在屏幕的一侧显示一个单词,并让另一个标签在另一侧显示一个相关单词的列表。

例如:当我点击按钮时,我希望主标签显示“猫”,列表显示“老虎”、“雪豹”、“狮子”等。输出将是随机的:显示的标签将是随机,列表将被打乱。

我通过将每个列表存储在 NSMutableArray 中并使用 NSDictionary 保存所有 NSArray,在 Xcode 4.3 控制台中实现了此输出。这是代码:

//creates lists
NSArray *catList = [NSArray arrayWithObjects:@"Lion", @"Snow Leopard", @"Cheetah", nil];
NSArray *dogList = [NSArray arrayWithObjects:@"Dachshund", @"Pitt Bull", @"Pug", nil]; 
...
//creates dictionary and stores lists values with dictionary keys
NSMutableDictionary *wordDictionary = [[NSMutableDictionary alloc] init];
[wordDictionary setObject: catList forKey:@"Cats"];
[wordDictionary setObject: dogList forKey:@"Dogs"]; 
...
//randomizes selection of dictionary key
NSInteger keyCount = [[wordDictionary allKeys] count];
NSInteger randomKeyIndex = arc4random() % keyCount;
//displays selected key, which is the main word
NSLog(@"%@", randomKey);
//selects array list corresponding to key
NSMutableArray *randomlySelectedArray = [wordDictionary objectForKey:randomKey];
//shuffles the output of the selected word list array
 for( int index = 0; index < keyCount; index++ )
            {
                int randomIndex = arc4random() % keyCount;
                [randomlySelectedArray exchangeObjectAtIndex:index withObjectAtIndex:randomIndex];
            }
//prints word list and removes displayed dictionary selection
 NSLog(@"%@", randomlySelectedArray);
[wordDictionary removeObjectForKey:randomKey];

(我需要添加确实显示一个主要单词并一次列出一个的代码,也许使用 NSTimer,但这是我到目前为止所得到的。)

在 Xcode 中使用单视图模板,通过将其中一些代码添加到我的视图控制器实现文件中按钮的 IBAction 方法,我已经能够让模拟器显示一个主词和相应的列表。(当然,我将 NSLog 更改为 initWithFormat。)但是,我的随机化代码都不起作用。

最后,我的问题是如何分离事物以使它们最符合 MVC 设计?我在想:我的按钮和我的两个标签构成了视图。我的视图控制器是控制器,我的 NSArrays 和 NSDictionary 数据是模型。

但是,我一直将所有模型数据保存在视图控制器中,我很确定这是错误的。我认为我需要弄清楚如何为我的 NSArrays 和 NSDictionary 创建一个类来存储我的模型数据。然后我必须设法让我的按钮和标签通过我的视图控制器显示我的模型数据的所需文本。至少我认为这就是 MVC 的工作方式。

我想知道这种理解是否正确,以及是否有人对如何最有效地组织我的模型数据以获得我想要的输出有任何指示。

非常感谢您的帮助!我被困住了!

4

1 回答 1

7

在开始设计基于 MVC 的应用程序之前。我们首先需要知道这些不同的组件是什么,以及 MVC 帮助我们实现什么?

为什么我们使用 MVC?(模型-视图-控制器)因为它可以帮助我们:

职责分离也带来了可重用性

通过最小化依赖关系,您可以获取已经编写的模型或视图类并在其他地方使用它

想办法写更少的代码

在设计基于 MVC 的应用程序时,我们应该关注以上几点。让我们将这个“字典”应用程序与现实世界的字典联系起来。

字典由单词、它们的含义、发音、例子、用法、反义词、同义词、索引和其他类似信息组成。当用户想要查找特定单词时,他将使用上边距单词进行快速查找。一旦他找到了正确的页面,他就会去那个词并查看它的含义、用法或其他需要的信息。

模型部分:

让我们在您的应用程序和我上面描述的内容之间进行类比。

在您的应用程序中,您将拥有一个类:'Dictionary',它将代表真实世界的字典。这本词典由单词、它们的含义、发音、用法和其他信息组成。所以我们需要一个包含“Word”对象的单词数组。“单词”类将包含我们希望为特定单词提供的所有信息。您还可以提供您认为属于 Dictionary 的其他属性并将它们添加到其中。(这里我们只讨论内容)

现在我们需要考虑在这个字典上执行不同的操作。最基本的操作是创建字典并访问它。

  1. 我们将有一个 DictionaryCreator 类,它将添加我们的字典将包含的所有单词。所以这是另一个类'DictionaryCreator'。或者我们可以将这个创建逻辑放在“字典”的 init 方法中。但是拥有这个类会很有帮助,这将启用字典添加词功能。

  2. DictionaryCreator 创建字典后,用户就可以使用它了。因此,我们需要提供用户可以在“字典”上执行的不同操作作为其方法。在我们的例子中,我们可以认为用户在控制器之上,实际上是由真实用户控制的。

上述技术将帮助您创建一个仅执行其职责的组件,并且可以在其他应用程序中重用或扩展以供将来使用。*永远记住模型是 MVC 设计中最可重用的组件。因此,每当您对模型有疑问时,只需提醒一下“模型必须可重用”。(不知道视图或控制器)

所以我们刚刚完成了应用程序的模型部分。

查看部分:

这取决于您,您希望为用户提供什么界面。但是让我们再次考虑现实世界的字典。真实世界词典的内容(信息)分布在多个页面上。这个视图帮助我们在字典中查看/访问/标记/书签。(请记住,这里是用户执行所有操作,而不是页面,也不是字典)。这些页面的顶部或底部有简单的查找单词,底部有一些发音指导。

在您的应用程序中,您说“我希望能够点击一个按钮并让一个标签在屏幕的一侧显示一个单词,并让另一个标签在另一侧显示一个相关单词的列表。”

在这里,我们再次有多个选项来实现这一点,您可以使用 Interface Builder 创建视图并将它们与您的控制器连接。但话又说回来,这个控制器和视图将紧密耦合,当我们希望在其他地方使用类似的接口时,我们将无法这样做。因此,为了可重用性,我们将创建另一个 UIView 类并使用新的 View XIB 创建它并加载此 nib。因此,将来如果您需要类似的视图,您可以轻松重用(例如 cocoa-touch 为我们提供了 UIView、UIButton 等)。

*View 也往往是 MVC 中的可重用组件。(不知道控制器,可能知道相关模型对象)

控制器部分:

现在我们已经创建了视图和模型,但它们将如何通信?控制器将在这方面帮助他们。控制器:

Knows about model and view objects
The brains of the operation 
Manages relationships and data flow 
Typically app-specific, so rarely reusable

*我从斯坦福大学讲座中获得的要点和定义[CS193P - 第 6 讲 iPhone 应用程序开发设计 iPhone 应用程序模型-视图-控制器(为什么和如何?)视图控制器]

更新:

最近,我遇到了另一个关于 MVC 的好讲座。它通过非常好的示例以更好的方式解释了这个设计概念。它可以在 iTunes U 上获得,或者您可以直接去iPad 和 iPhone 应用程序开发 (SD)的 Paul Hegarty 的第一讲。

于 2012-03-01T04:54:00.270 回答