6

在使用 iOS 和 Mac 目标 C 框架编程一段时间后,我开始喜欢由 NSNotificationCenter 和 NSNotification 类实现的通用通知模式。回到 C++,它一直是我在大多数事情上的首选语言,我发现自己在尝试复制这种模式,并相信确实应该已经存在类似 C++ 类的通用实现,为它提供支持。

看起来这种模式在 C++ 中比 Objective C 更难实现,因为后者更具动态性,但似乎远非不可能。我浏览了 boost 库,因为它们通常很棒,很遗憾没有在那里找到我的运气。尽管 boost::bind、boost::lamda、boost::function 似乎完成了大部分工作。我错过了什么明显的东西吗?是否已经存在任何可以让我轻松复制 NSNotification/NSNotificationCenter 行为的东西?

4

3 回答 3

3

理论上,您可以创建一个类,该类具有在调用某个通知时要调用的函数指针向量 - 具有字典的类,其中对象是推送通知时要调用的函数向量

于 2011-11-05T04:52:09.877 回答
3

除了boost其他答案中提到的包之外,另一个选项是poco::NotificationCenter.

这个实现更接近于 Cocoa 通知框架,具体讨论在 Poco 的文档中:

NotificationCenter 类基本上是在 Apple 的 Cocoa(或 OpenStep)中找到的 NSNotificationCenter 类的 C++ 实现。

于 2015-02-06T14:17:46.830 回答
1

遵循@anno 的建议来查看 boot::signal,经过检查,它确实是一个可能的选择,尽管正如预期的那样,它不像目标 C 解决方案那样直接。浏览boost::signal 教程,我想我会针对手头的问题了解最相关的方面。


要创建通知发件人:

考虑一个简单的新闻传递服务,其中客户端连接到新闻提供者,然后在信息到达时将新闻发送给所有连接的客户端。新闻传递服务可以这样构建:

class NewsItem { /* ... */ };
boost::signal<void (const NewsItem&)> deliverNews;

的目的deliverNews是通知观察者 aNewsItem已经生成。


可以按如下方式添加观察者(使用 boost::bind 库):

希望接收新闻更新的客户端只需将可以接收新闻项目的函数对象连接到 DeliverNews 信号。例如,我们的应用程序中可能有一个专门用于新闻的特殊消息区域,例如:

struct NewsMessageArea : public MessageArea
{
public:
  // ...

  void displayNews(const NewsItem& news) const
  {
    messageText = news.text();
    update();
  }
};

// ...
NewsMessageArea newsMessageArea = new NewsMessageArea(/* ... */);
// ...
deliverNews.connect(boost::bind(&NewsMessageArea::displayNews, newsMessageArea, _1));

为了解决从列表中删除已被释放的观察者的问题,boost::signal 提供了以下解决方案

但是,如果用户关闭新闻消息区域,破坏了 DeliverNews 知道的 newsMessageArea 对象怎么办?很可能会发生分段错误。但是,使用 Boost.Signals 只需要将 NewsMessageArea 设为可跟踪,当 newsMessageArea 被销毁时,涉及到 newsMessageArea 的 slot 将被断开。NewsMessageArea 类是通过从 boost::signals::trackable 类公开派生而来的,例如:

struct NewsMessageArea : public MessageArea, public boost::signals::trackable
{
  // ...
};

此时,在进行槽连接时使用可跟踪对象有很大的限制:可以理解使用 Boost.Bind 构建的函数对象,以便找到并跟踪传递给 boost::bind 的可跟踪对象的指针或引用。

于 2011-11-05T15:36:16.123 回答