1

我来自 .NET Web 应用程序背景,刚刚开始 iOS 开发。我的应用程序的初始设计侧重于 NSNotificationCenter。我对此相当满意,直到我看到各种帖子解释如何到达 NSNotificationCentre 是一个常见的新手错误。

这是我要解决的问题的简化版本:

我的应用程序试图显示使用 Web 服务调用填充的消息列表,想想 Facebook 消息传递。

首次加载应用程序时,它会从服务器拉取一组消息并将它们显示在一个表格中给用户。用户可以添加新消息(通过 API 发回),应用程序可以接收有关添加到提要的新消息的推送通知。

消息永远不会保存到磁盘上,所以我只是使用 POCO 作为模型来保持简单。

我有一个 MessageFeedController 负责填充消息提要视图(在故事板中)。我还有一个消息提要模型,它存储当前检索到的值并具有各种方法:

  • (void) loadFromServer;
  • (void) createMessage: (DCMMessage*) 消息;
  • (void) addMessage: (DCMMessage*) 消息;
  • (NSArray*) 消息;
  • (int) 未读消息;

我目前的实现是这样的:

用例 1:初始负载

  1. 当视图首次出现时,会调用“loadFromServer”方法。这会填充消息集合并引发 NSNotificationCenter 事件。
  2. 控制器观察到这个事件,并在收到它时填充表格视图

用例 2:新消息

  1. 当用户单击“添加”按钮时,会出现一个新视图,他们输入他们的消息,点击发送,然后视图被关闭。
  2. 这会调用模型上的 createMessage 方法,该方法调用 API
  3. 一旦我们得到响应,模型就会引发 NSNotificationCenter 事件
  4. MessageFeedController 再次侦听此事件并重新填充表

用例 3:推送消息

  1. 应用程序打开时收到推送通知,其中包含新消息详细信息
  2. AppDelegate(或其他类)将调用模型上的 addMessage 方法,将其添加到集合中
  3. 再一次,假设 MessageFeed 视图是打开的,它会重新填充

在所有三种情况下,MessageFeed 视图都会更新。除此之外,BadgeManager 还监听这些事件,这些事件负责设置应用程序图标徽章和标签栏徽章,在这两种情况下,徽章编号都与未读消息的数量有关。

另一个视图也可能打开并正在侦听这些事件,该视图包含消息摘要,因此需要知道集合何时更改。

是的,感谢您的支持,我的问题是:这似乎是对 NSNotificationCentre 的有效使用,还是我滥用了它?

我担心的一个问题是,如果消息集合在重新填充消息表的过程中发生变化,我不能 100% 确定会发生什么。我唯一能看到这种情况发生的情况是收到关于新消息的推送通知。在这种情况下,表格的人口是否必须在对 NSNotification 采取行动之前完成?

谢谢你的帮助

担。

4

3 回答 3

3

换句话说,只要消息列表更新,您就会发布通知。这是对 NSNotificationCenter 的完全有效的使用。

另一种选择是使用Key-Value Observing

您的控制器(和其他任何人)可以注册为“消息”属性的观察者,并且会在该属性更改时收到通知。在模型方面,您可以免费获得 KVO;只需调用一个名为的方法setMessages:将触发 KVO 更改通知。您还可以手动触发通知,如果需要,KVO 通知可以包括已添加、删除或更改的数组索引。

KVO 是执行此类更改通知的标准化方式。在使用Cocoa Data Binding实现 OS X 应用程序时,这一点尤为重要。

NSNotificationCenter 更加灵活,您可以将任何附加信息与每个通知捆绑在一起。

确保您的消息列表仅在主线程上更新,并且消息列表在没有发布相应的更改通知的情况下永远不会被修改,这一点很重要。您的控制器还应该注意忽略这些通知,只要它不是最顶层的视图控制器或不在屏幕上。在 中注册更改通知viewWillAppear:并在中取消注册的情况并不少见viewWillDisappear:

于 2012-11-19T17:04:40.780 回答
1

在我看来,使用委托协议模式将更适合这种情况。考虑您的“api 层”需要在应用程序中的多个视图控制器中使用的场景。如果要向其他开发人员介绍您的代码,他们将不得不四处寻找通知中心订阅,而不是仅仅遵循类似协议的干净“接口”。

话虽如此,您的代码可以正常工作,这是对通知中心的有效使用。使用基于协议的方法只是我个人对“更清洁”代码的偏好。看看 iOS SDK 本身,你会看到 Apple 自己使用协议和使用通知的场景。我觉得理解和使用协议比必须四处挖掘并确定我必须听什么通知要容易得多。

于 2012-11-19T17:07:18.357 回答
1

NSNotifications接收者代码在发布后立即同步运行,因此重新填充期间的新消息将加入该执行队列的后面。总的来说,这对我来说似乎是有效的,并且它在视图控制器和模型之间保持了合理的分离程度。

Depending on the number of classes that are likely to want to listen for the same information arriving, you may want to use a delegate pattern, maybe keeping an dictionary of delegate objects, but I personally don't feel as though this scales so well, and you also have to take care of nil-ing out delegates if a page is dealloced to avoid crashes. To sum up, your approach seems good to me.

于 2012-11-20T12:17:32.453 回答