C++ 通知中心

发布于 2024-12-13 22:40:06 字数 408 浏览 4 评论 0原文

在使用 iOS 和 Mac Objective C 框架进行了一段时间的编程之后,我开始喜欢上 NSNotificationCenter 和 NSNotification 类实现的通用通知模式。回到 C++,它一直是我在大多数事情上选择的语言,我发现自己正在尝试复制这种模式,并相信实际上应该已经有一个类似的 C++ 类的通用实现来提供对其的支持。

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

After programming for sometime with the iOS and Mac objective C frameworks, I have come to love the generic notification pattern implemented by the NSNotificationCenter and NSNotification classes. Coming back to C++, which has always been my language of choice for most things, I find myself trying to replicate this pattern and believe there should really already be a generic implementation of similar C++ classes offering support for it out there.

It does seem like the pattern is somewhat more difficult to implement in C++ than Objective C because of the more dynamic nature of the later, but it seems far from impossible. I've looked through the boost libraries as they are generally awesome and was sad not to find my luck there. Although the boost::bind, boost::lamda, boost::function seem like they do most of the work. Have I missed something obvious? Is there anything already existing out there that would allow me to easily replicate NSNotification/NSNotificationCenter behaviour?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

少年亿悲伤 2024-12-20 22:40:06

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

In theory you could create a class that has a vector of function pointers to call when a certain notification is called - A class that has a dictionary where the objects are the vectors of functions to call when a notification is pushed

海的爱人是光 2024-12-20 22:40:06

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

此实现更接近 Cocoa 通知框架,正如 Poco 的文档中具体讨论的那样:

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

In addition to the boost packages mentioned in other answers, another option is poco::NotificationCenter.

This implementation is closer to the Cocoa notification framework, as specifically discussed on Poco's documentation:

The NotificationCenter class is basically a C++ implementation of the
NSNotificationCenter class found in Apple's Cocoa (or OpenStep).

墨洒年华 2024-12-20 22:40:06

按照 @anno 建议查看 boot::signal 的建议,经过检查,它似乎是一个可能的选择,尽管正如预期的那样,它不像目标 C 解决方案那么简单。浏览 boost::signal 教程,我想我会讨论与当前问题最相关的方面。


创建通知发送者:

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

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

deliverNews 的目标是通知观察者 NewsItem 已生成。


可以按如下方式添加观察者(使用 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 将被断开
被毁了。 NewsMessageArea 类通过派生变得可跟踪
从 boost::signals::trackable 类公开,例如:

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

目前可追踪的使用存在重大限制
建立槽连接的对象:使用构建的函数对象
Boost.Bind 是可以理解的,这样指向的指针或引用
传递给 boost::bind 的可跟踪对象将被找到并跟踪。

Following @anno's recommendation to look at boot::signal, it does after examination seem like a possible option although it is, as expected, not as straight-forward as the objective C solutions. Looking through the boost::signal tutorial, I thought I would go through the most relevant aspects for the problem at hand.


To create notification senders:

Consider a simple news delivery service, where clients connect to a news provider that then sends news to all connected clients as information arrives. The news delivery service may be constructed like this:

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

The objective of deliverNews is to inform observers that a NewsItem has been generated.


Observers can be added as follows (using the boost::bind library):

Clients that wish to receive news updates need only connect a function object that can receive news items to the deliverNews signal. For instance, we may have a special message area in our application specifically for news, e.g.,:

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));

To address the problem of removing observers which have been deallocated from the list, boost::signal offers the following solution

However, what if the user closes the news message area, destroying the
newsMessageArea object that deliverNews knows about? Most likely, a
segmentation fault will occur. However, with Boost.Signals one need
only make NewsMessageArea trackable, and the slot involving
newsMessageArea will be disconnected when newsMessageArea is
destroyed. The NewsMessageArea class is made trackable by deriving
publicly from the boost::signals::trackable class, e.g.:

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

At this time there is a significant limitation to the use of trackable
objects in making slot connections: function objects built using
Boost.Bind are understood, such that pointers or references to
trackable objects passed to boost::bind will be found and tracked.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文