6

iOS および Mac のオブジェクティブ C フレームワークでしばらくプログラミングした後、NSNotificationCenter および NSNotification クラスによって実装される汎用通知パターンが好きになりました。C++ に戻ると、C++ は、ほとんどの場合に常に選択する言語であり、このパターンを複製しようとしていることに気づき、それをサポートする同様の C++ クラスの汎用実装が実際に既に存在するはずだと考えています。

パターンを C++ で実装するのは、Objective C のより動的な性質のため、Objective C よりもいくらか難しいように見えますが、不可能ではないようです。ブーストライブラリは一般的に素晴らしいものであり、そこで運が見つからないのは残念だったので、調べました。boost::bind、boost::lamda、boost::function はほとんどの作業を行っているように見えますが。明らかな何かを見逃しましたか?NSNotification/NSNotificationCenter の動作を簡単に複製できるものは既に存在しますか?

4

3 に答える 3

3

理論的には、特定の通知が呼び出されたときに呼び出す関数ポインターのベクトルを持つクラスを作成できます-オブジェクトが通知がプッシュされたときに呼び出す関数のベクトルである辞書を持つクラス

于 2011-11-05T04:52:09.877 に答える
1

boot::signal を調べるという @anno の推奨に従って、検討した結果、可能なオプションのように見えますが、予想どおり、目的の 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 に渡された追跡可能オブジェクトへのポインターまたは参照が検出され追跡されるように理解されます。

于 2011-11-05T15:36:16.123 に答える