模型和控制器之间的通信 - iOS

Posted

技术标签:

【中文标题】模型和控制器之间的通信 - iOS【英文标题】:Communication between Model and Controller - iOS 【发布时间】:2012-04-27 08:39:40 【问题描述】:

我是 ios 开发的新手,希望能得到一些反馈。

我正在尝试为我的 Web 服务构建一个 iOS 客户端。到目前为止,这就是我所做的:

我正在实现两个视图(使用 Storyboard 的基于实用程序的应用程序)。在主视图中,我使用了一个文本字段和一个搜索按钮,用户可以在其中输入查询,然后单击搜索按钮。单击搜索按钮后,我的意图是读取文本字段的值,并将其用于对我的 Web 服务的 Restful 调用。我的 Web 服务返回一个带有查询结果的 JSON 文件,我对其进行解析并显示到辅助视图的文本区域。

我知道如何在 iOS 中进行 restful 调用以及如何进行 JSON 解析以及在屏幕上显示结果(至少是文本内容,但这是另一个不同的问题)。但我的目的是学习 MVC 基础知识并将其应用到我的应用程序中。

根据MVC,控制器更新视图,模型发出通知广播,控制器可以监听并知道对象是否有任何变化。所以这是我最想做的事情:

我的模型 - 我的模型将处理核心 RESTful 调用、获取 JSON 回复、解析它并获取我想要在视图上显示的结果值。

我的控制器 - 我希望我的控制器监听我的模型并从模型中获取结果值并将它们显示在视图上。

使用一种快速而肮脏的方式,我可以实现 RESTful 调用、JSON 解析和显示结果值 - 所有这些都在 Controller 中,但是使用这种技术,如果我的视图明天发生变化,那么我必须重新编写我的代码。或者如果我想添加新功能,那么我必须更改我的控制器。所以理想情况下,我希望有一个不知道 View 是什么样子的核心模型,让控制器从模型中获取结果并将它们显示在 View 上。

根据我目前从 Google 搜索结果中看到的信息,有两种方法是:a)键值观察和 b)通知中心。

在过去的 2 天里,我正在尝试找到一种不错的方式来实施通知中心或阅读更多相关信息,但我没有得到很好的线索。我的一些问题是,我可以使用控制器获取的通知中心发送字符串结果值吗?通知中心如何真正使用字符串值?我在哪里可以找到一些好的例子?

因此,我们将非常感谢任何有关此方面的帮助。

【问题讨论】:

您真的希望您的模型处理与 RESTful 服务的通信吗? 【参考方案1】:

我的一些问题是,我可以发送字符串结果吗 使用我的控制器获取的通知中心的价值?

是的,这通常使用NSNotificationuserInfo 属性来完成。 userInfo 是一个普通的NSDictionary,它可能包含由遵循NSCopying 协议的键索引的NSObject 派生对象的实例(通常使用NSString)。请注意,字典 (userInfo) 将保留您的参数对象。


通知中心如何真正处理字符串值?

嗯,这取决于您希望它如何工作。但抛开吹毛求疵,见下文。


我在哪里可以找到一些好的例子?

也许这个有帮助...


示例

接收者(控制器)注册通知:

- (void)registerForNotifications

    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(modelObjectUpdatedString:)
                                                 name:@"StringUpdated"
                                               object:nil];

发送者(模型)通知世界:

- (void)stringUpdateWith:(NSString *)theString

    self.string = theString;
    [[[NSNotificationCenter defaultCenter] postNotificationName:@"StringUpdated" 
                                                         object:self 
                                                       userInfo:[NSDictionary dictionaryWithObjectsAndKeys:self.string, @"String", nil]];

接收者(控制器)在其处理程序中接收通知:

- (void)modelObjectUpdatedString:(NSNotification *)notification

    ModelObject *postingObject = [notification object];
    NSString *string = [[notification userInfo]
        objectForKey:@"String"];
    ...

【讨论】:

这是一个完美的答案。非常感谢您提供清晰简洁的答案。这正是我想要的。【参考方案2】:

您的想法是正确的,但仍不完全正确。正如 Till 在他的评论中“指出”的那样,您不应该在模型中处理 RESTful 通信。如果我是你,我会创建一个负责获取信息的实用程序类,然后创建一个负责保存数据的类(最后一个类是你的模型)。

创建一个类方法来分配和启动该对象的一个​​新实例是很聪明的,该实例是从通过您的 RESTful 通信器类获取的 JSON 数据创建的。

从您的控制器的角度来看:

RESTHelper *rest = [RESTHelper restHelperWithURL:yourRESTURL];
YourModel *model = [YourModel modelWithJSON:[rest fetchObjectWithID:1]];
// Present your models data in the view.

您可能会从这里使用 CoreData 中受益,我强烈建议您研究一下。

【讨论】:

这里有好的提示。谢谢你指引我正确的方向。这些是我希望得到的反馈,因为我是 iOS 开发的新手,我希望在开发任何复杂的应用程序之前先掌握基础知识。 你不应该使用 NSNotificationCenter 除非你遇到块、KVO 或委托无法完成工作的情况。 嗨 Rasmus,我也开始接触 IOS。 (对 OO 来说不是那么新)。然后你会建议 restHelper 类“回调”到模型上的协议,一旦它得到一些数据?您能解释一下为什么使用 [rest fetchObjectWithID:1] 吗?我知道我在斯坦福的视频中看到过它,但似乎我已经破坏了那些脑细胞......

以上是关于模型和控制器之间的通信 - iOS的主要内容,如果未能解决你的问题,请参考以下文章

日期选择器组件之间的控制器间通信

iOS 模型层通知控制器对象

iOS设计模式初识-02

Java内存模型

Java 多线程与并发:内存模型

控制器可以捕获模型抛出的异常吗?