jba*_*100 6 c++ notifications objective-c cocoa-design-patterns nsnotificationcenter
在使用iOS和Mac目标C框架编程一段时间之后,我开始喜欢NSNotificationCenter和NSNotification类实现的通用通知模式.回到C++,它一直是我大多数事情的首选语言,我发现自己试图复制这种模式,并且相信应该真的已经存在类似C++类的通用实现,为它提供支持.
看起来这种模式在C++中比在Objective C中更难实现,因为后者的动态性更强,但这似乎是不可能的.我已经查看了升级库,因为它们通常很棒,很遗憾没有在那里找到我的运气.虽然boost :: bind,boost :: lamda,boost :: function看起来像是完成了大部分工作.我错过了一些明显的事吗?是否有任何已经存在的内容可以让我轻松复制NSNotification/NSNotificationCenter行为?
按照 @anno 建议查看 boot::signal 的建议,经过检查,它似乎是一个可能的选择,尽管正如预期的那样,它不像目标 C 解决方案那么简单。浏览boost::signal 教程,我想我会讨论与当前问题最相关的方面。
创建通知发送者:
考虑一个简单的新闻传送服务,其中客户端连接到新闻提供者,然后当信息到达时,新闻提供者将新闻发送到所有连接的客户端。新闻传送服务可以这样构建:
class NewsItem { /* ... */ };
boost::signal<void (const NewsItem&)> deliverNews;
Run Code Online (Sandbox Code Playgroud)
的目的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));
Run Code Online (Sandbox Code Playgroud)
为了解决从列表中删除已释放的观察者的问题,boost::signal 提供了以下解决方案
但是,如果用户关闭新闻消息区域,从而破坏了 DeliverNews 知道的 newsMessageArea 对象,该怎么办?最有可能的是,会发生分段错误。然而,使用Boost.Signals,只需使NewsMessageArea可跟踪,并且当newsMessageArea被销毁时,涉及newsMessageArea的槽将被断开。NewsMessageArea 类通过从 boost::signals::trackable 类公开派生而变得可跟踪,例如:
struct NewsMessageArea : public MessageArea, public boost::signals::trackable
{
// ...
};
Run Code Online (Sandbox Code Playgroud)
此时,在建立槽连接时使用可跟踪对象有一个显着的限制:使用 Boost.Bind 构建的函数对象是可以理解的,这样传递给 boost::bind 的可跟踪对象的指针或引用将被找到并跟踪。