您可以采取更简单的方法来解决您的问题。例如,我会考虑研究QtConcurrent框架。或者,您也可以重新设计您的设计,以便客户端首先连接到缓存上的“完成”信号,然后再要求缓存执行任何操作。如果所有这些都失败了,您还可以考虑依赖QMetaObject::invokeMethod函数(对于您的客户端或您的缓存)。此函数允许您使用任意泛型参数(以线程安全的方式)调用任意 QObject 上的任意方法(前提是您有指向它的指针)。
如果您使用该QMetaObject::invokeMethod
方法,则应该注意一些缺点。首先,您必须使用它的字符串名称来调用该方法,这意味着您在编译时不会发现您是否使用了错误的名称。其次,由于您的客户端与中央缓存具有不同的线程亲和性,因此当缓存调用它们上的方法时,客户端有可能已被销毁(尽管在您的情况下,这对您来说不是问题) . 最后,您可能不希望您的缓存知道它必须在其客户端上执行的方法的名称。
我没有办法解决第一个缺点(我不确定在即将发布的 Qt 5.0 版本中是否会以不同的方式处理)。至于第二个和第三个问题,我建议创建一个封装对方法的引用的对象——如下所示:
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;
};
然后,您可以将此对象从客户端传递到您的缓存。然后缓存调用这个对象的调用。
请注意使用QPointer
-- 这为您提供了一种线程安全的方法,可以在您尝试对其调用方法之前检查您的对象是否已被销毁。因为我以前做过,所以我也会告诉你,4.8 之前的 Qt 版本有一个错误QPointer
,会导致多线程上下文中的崩溃。如果您想这样做,请使用更新版本的 Qt。
我希望这很清楚。