这是NSNotificationCenter的有效使用

时间:2012-11-19 15:55:54

标签: objective-c ios ios5

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

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

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

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

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

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

  • (void)loadFromServer;
  • (void)createMessage:(DCMMessage *)message;
  • (void)addMessage:(DCMMessage *)message;
  • (NSArray *)消息;
  • (int)unreadMessages;

我目前的实施是:

用例1:初始加载

  1. 当视图首次出现时,将调用“loadFromServer”方法。这将填充消息集合并引发NSNotificationCenter事件。
  2. 控制器会观察此事件,并在收到时填充tableview
  3. 用例2:新消息

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

      1. 在应用程序打开时收到推送通知,其中包含新邮件详细信息
      2. AppDelegate(或其他一些类)将在模型上调用addMessage方法,将其添加到集合中
      3. 再次假设MessageFeed视图已打开,它会重新填充
      4. 在所有三种情况下,都会更新MessageFeed视图。除此之外,BadgeManager还会监听这些事件,这些事件负责设置应用程序图标徽章和标签栏徽章,在这两种情况下,徽章编号都与未读邮件的数量相关。

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

        是的,谢谢你坚持我,我的问题是:这看起来像是对NSNotificationCentre的有效使用,还是我误用了它?

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

        感谢您的帮助

3 个答案:

答案 0 :(得分:3)

换句话说,每当更新邮件列表时,您都会发布通知。这是对NSNotificationCenter的完全有效的使用。

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

您的控制器(以及其他任何人)可以注册为“messages”属性的观察者,并在该属性发生更改时通知您。在模型方面,你可以免费获得KVO;只需调用名为setMessages:的方法即可触发KVO更改通知。您也可以手动触发通知,如果需要,KVO通知可以包括添加,删除或更改阵列的哪些索引。

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

NSNotificationCenter更灵活,您可以将每个通知捆绑任何其他信息。

确保您的邮件列表仅在主线程上更新,并且永远不会修改邮件列表而不发布相应的更改通知也很重要。只要控制器不是屏幕上最顶层的视图控制器,您的控制器也应该小心忽略这些通知。在viewWillAppear:注册变更通知并在viewWillDisappear:取消注册的情况并不少见。

答案 1 :(得分:1)

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

话虽如此,您的代码将正常运行,这是通知中心的有效使用。我个人倾向于使用基于协议的方法来使用“更干净”的代码。浏览iOS SDK本身,您将看到Apple自己使用协议和使用通知的情况。我觉得理解和使用协议要比挖掘并确定我必须听取通知的内容要容易得多。

答案 2 :(得分:1)

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

根据可能想要侦听相同信息的类的数量,您可能想要使用委托模式,也许保留委托对象的字典,但我个人觉得这并不像如果页面被取消分配以避免崩溃,你还必须照顾代表。总而言之,你的方法对我来说似乎很好。