問題を解決するためのより簡単な方法があるかもしれません。たとえば、QtConcurrentフレームワークを調べることを検討します。または、キャッシュに何かを要求する前に、クライアントが最初にキャッシュの「終了」シグナルに接続するように、設計を再構築することもできます。そのすべてに失敗した場合は、 QMetaObject::invokeMethod関数 (クライアントまたはキャッシュのいずれか) に依存することを検討することもできます。この関数を使用すると、(スレッドセーフな方法で) 任意のジェネリック引数を使用して、任意の QObject (それへのポインターがある場合) で任意のメソッドを呼び出すことができます。
このアプローチを使用する場合QMetaObject::invokeMethod
、いくつかの欠点に注意する必要があります。まず、文字列名を使用してメソッドを呼び出す必要があります。つまり、間違った名前を使用しているかどうかがコンパイル時にわかりません。第二に、クライアントは中央キャッシュとは異なるスレッド アフィニティを持っているため、キャッシュがそれらのメソッドを呼び出したときにクライアントが破棄される可能性があります (ただし、おそらくあなたの場合、これは問題にはなりません)。 . 最後に、クライアントで実行する必要があるメソッドの名前をキャッシュに認識させたくない場合があります。
最初の欠点を回避する方法はありません (今後の Qt 5.0 リリースでこれが異なる方法で処理されるかどうかはわかりません)。2 番目と 3 番目の問題に関しては、メソッドへの参照をカプセル化するオブジェクトを作成することをお勧めします。次のようなものです。
class MethodReference
{
MethodReference(QObject* object, const QString& methodName);
...
bool invoke(QGenericArgument val0 = QGenericArgument(),
QGenericArgument val1 = QGenericArgument(),
...
QGenericArgument val9 = QGenericArgument());
private:
QPointer<QObject> mObject;
QString mMethod;
};
次に、このオブジェクトをクライアントからキャッシュに渡します。次に、キャッシュはこのオブジェクトで invoke を呼び出します。
--の使用に注意してください。QPointer
これにより、メソッドを呼び出す前に、オブジェクトが破棄されているかどうかをスレッドセーフに確認できます。以前にこれを行ったので、Qt の 4.8 より前のバージョンには、マルチスレッド コンテキストでクラッシュを引き起こすバグがQPointer
あったこともお知らせします。これを行う場合は、より新しいバージョンの Qt を使用してください。
これが明確だったことを願っています。