如何拥有一个QNetworkAccessManager实例? [英] How to have one instance of QNetworkAccessManager?

查看:443
本文介绍了如何拥有一个QNetworkAccessManager实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个类似的问题,但是我发现它对解决问题没有帮助我的问题.

There is a similar question but I did not find it useful for my problem.

在Qt 文档中,他们说:

对于整个Qt应用程序,一个QNetworkAccessManager实例就足够了.

One QNetworkAccessManager instance should be enough for the whole Qt application.

在我的应用程序中,我在多个地方(它们可能同时被调用)使用QNetworkAccessManager,每次我在堆栈上创建新实例时.阅读完引用后,我将代码更改为具有一个静态QNetworkAccessManager并在各处使用它.将其更改为静态成员后,我总是收到警告:

In my application, I was using QNetworkAccessManager in several places (they may be called simultaneously) and each time I was creating new instance on the stack. After reading that quote I changed my code to have one static QNetworkAccessManager and using it everywhere. After changing it to static member, I always get a warning:

QObject::connect: Cannot connect (null)::aboutToQuit() to QNativeWifiEngine::closeHandle()

在这两种情况下,代码都可以正常工作,但是文档使我有些困惑.由于该产品将要商业化,因此我非常重视此问题.我应该遵循文档说明还是避免警告?还是您建议其他方法?

In both cases, the code is working without errors, however, that documentation is confusing me a little bit. As the product is going to be commercial, I am taking this issue serious. Should I follow a documentation or avoid a warning? Or do you suggest any other ways?

如果不同线程上的对象需要使用QNetworkAccessManager怎么办?

What if an object on a different thread needs to use a QNetworkAccessManager?


添加代码

单个设置类别:

class ConnectionSettingsSingleton
{
   ...
   // constructors = default
   // copy constructor = delete

   public:
      static QNetworkAccessManager networkAccessManager;
}

我在不同的地方使用networkAccessManager,但是使用的方式相同:

I use networkAccessManager in different places, but the same way:

QNetworkReply* HttpClient::makeRequest()
{
   switch (this->method) {
   case RequestMethod::GET:
      return ConnectionSettingsSingleton::networkAccessManager.get(this->serverRequest);
   case RequestMethod::POST:
      return ConnectionSettingsSingleton::networkAccessManager.post(this->serverRequest, QJsonDocument(this->data).toJson());
   case RequestMethod::DELETE:
      return ConnectionSettingsSingleton::networkAccessManager.deleteResource(this->serverRequest);
   default:
      return nullptr;
   }
}


编辑2

我一直在使用库巴·奥伯的答案,有一次我得到了这个警告:

I was kindly using Kuba Ober's answer and at one point I got this warning:

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QNetworkAccessManager(0x26f6d0), parent's thread is QThread(0x2b73b8), current thread is QThread(0xa4f20a8)

原因:我尝试从其他线程访问QNAM.因此,我更新了我的问题.

Reason: I tried to access QNAM from a different thread. Accordingly, I updated my question.

推荐答案

您可以使用整个Qt.请勿为此使用静态变量-您无法控制它们的生命周期,并且生命周期几乎总是错误的. QCoreApplication不存在时,QNetworkManager不应该存在.该警告根本不是良性的-它表示一个基本的设计问题. ,您需要控制管理器的生命周期,并确保它不会超过QApplication.管理此类全局应用程序绑定对象的规范方法是将其保留为main中的自动变量,并使用辅助函数来访问它们. QPointer自动跟踪对象的寿命,因此永远不会晃来晃去.因此:

You have entire Qt at your disposal. Do not use static variables for this - you don't control their lifetime, and that lifetime is almost always wrong. The QNetworkManager should not exist when QCoreApplication doesn't exist. The warning is not benign at all - it indicates a fundamental design issue. You need to control the lifetime of the manager, and ensure that it doesn't outlive QApplication. The canonical way to manage such global application-tied objects is to keep them as automatic variables in main and use helper functions to access them. The QPointer automatically tracks the lifetime of the object, and thus won't ever be dangling. Thus:

QNetworkAccessManager *nMgr();

main.cpp-实现

// This pointer is local to the translation unit, and is an
// implementation detail. It's not used anywhere else.
static QPointer<QNetworkAccessManager> globalManager;

// The global accessor method
QNetworkAccessManager *nMgr() {
  Q_ASSERT(!qApp || QThread::currentThread() == qApp->thread());
  return globalManager;
}

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);
  QNetworkAccessManager mgr;
  globalManager = &mgr;
  ...
}

这篇关于如何拥有一个QNetworkAccessManager实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆