作者热门文章
- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
这个问题源于一个question我之前问过。
简而言之,图像提供者抽象类需要实现一种通过参数“url”请求图像并返回图像的方法。例如。单个方法请求并返回图像。但是 Qt 的 QNetworkAccessManager
类是严格为异步使用而设计的,例如您以一种方法请求 url 并通过连接到请求完成后发出的信号来拦截它。例如。它必须分为两个步骤,这就提出了一个问题,即如何使用一个旨在被分解的类来实现图像提供者所需的单一方法(考虑到我用来强制它同步的 hack 导致一团糟)?
最佳答案
一般的回答是:它不能安全地完成。虽然在特定情况下可以这样做,但需要仔细检查所涉及的代码,并提供一些证据证明不存在由于重入导致的问题。
至于同步类的使用,您只需要在requestXxxx
方法的实现中运行一个本地事件循环。如果它在专用线程中运行,那么重入问题就不那么重要了,因为您可以控制哪些对象在线程中处于事件状态。
由于您的 QQuickImageProvider
实现可以指定 ForceAsynchronousImageLoading
标志,因此您的提供程序将在其自己的线程中运行,并且可以安全地运行其自己的消息循环。
请注意,默认的 QML 图像提供程序将 URI 作为输入,并且非常乐意从网络加载图像 - 因此在这种情况下您不必担心。
因此,即使您的自定义图像提供程序完全没有必要,如果您要创建它,也可以按照以下方式进行:
class MyImageProvider : public QQuickImageProvider {
public:
MyImageProvider();
Flags flags() const { return ForceAsynchronousImageLoading; }
QImage requestImage(const QString & id, QSize * size, const QSize & requestedSize)
Q_DECL_OVERRIDE;
}
QImage MyImageProvider::requestImage(
const QString & id, QSize * size, const QSize & requestedSize)
{
QImage image;
QEventLoop loop;
QNetworkAccessManager mgr;
QObject::connect(&mgr, &QNetworkAccessManager::finished,
[&loop, size](QNetworkReply* reply) {
image.load(reply, "JPG");
if (size) *size = image.size();
loop.quit();
delete reply;
});
mgr.get(QNetworkRequest(QUrl(id)));
loop.exec();
return image;
}
关于c++ - 如何使异步 API 符合需要同步性的 API?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25937975/
我是一名优秀的程序员,十分优秀!