Unsolved QNetworkAccessManager at global scope
-
I want to use QNetworkAccessManager from a global function (not a class member).
I've got the beginnings of a concept - below:
void ::replyFinished(QNetworkReply * reply) { QByteArray buffer = reply->read(reply->bytesAvailable()); reply->deleteLater(); } bool CheckVersion(CString & strVersion) { static QNetworkAccessManager manager; QObject::connect(&manager, &QNetworkAccessManager::finished, ::replyFinished); manager.get(QNetworkRequest(QUrl("http://deepskystacker.free.fr/download/CurrentVersion.txt"))); }
But that leaves the manager object lying around when the job is done.
Can I use a pointer to QNetworkAccessManager and call deleteLater() to delete that as well?
Help most welcome
David -
@Perdrix said in QNetworkAccessManager at global scope:
I want to use QNetworkAccessManager from a global function
Why?
Global objects are almost always a sign of bad design. -
Yes, but a major application redesign of legacy code is not something one undertakes lightly!
I've actually moved the code into a class now rather than having it as global.
Q about deleteLater still applies ...
-
Hi,
Usually QNetworkManager is used as a class variable and thus destroyed along with said class. There's no real need to put it on the heap. But if you need to, just give it a parent and it will be destroyed with it.
-
Is static safe within a function in relation not being initialized before QApplication?
-
@mrjj good question, I did not even consider it an option and I currently don't know for sure. I would stay in the line of: do not allocate static QObject based classes.
-
@SGaist
It seems that its first called on first use when its not a POD.Frankly im not sure either. I rarely use static inside functions as its rarely truly useful and
very annoying for unit testing with mockups. -
It's now allocated on the the heap:
Here's the current code for comments (networkManager is an mv of CStackingDlg):
void CStackingDlg::versionInfoReceived(QNetworkReply * reply) { QString string(reply->read(reply->bytesAvailable())); if (string.startsWith("DeepSkyStackerVersion=")) { QString verStr = string.section('=', 1, 1); int version = verStr.section('.', 0, 0).toInt(); int release = verStr.section('.', 1, 1).toInt(); int mod = verStr.section('.', 2, 2).toInt(); if ((version > DSSVER_MAJOR) || (version == DSSVER_MAJOR && release > DSSVER_MINOR) || (version == DSSVER_MAJOR && release == DSSVER_MINOR && mod > DSSVER_SUB) ) { CString strNewVersion; strNewVersion.Format(IDS_VERSIONAVAILABLE, CString((wchar_t *)verStr.utf16())); m_Infos.SetTextColor(RGB(255, 0, 0)); m_Infos.SetText(strNewVersion); m_Infos.SetLink(true, false); m_Infos.SetHyperLink("https://github.com/deepskystacker/DSS/releases/latest"); }; } reply->deleteLater(); networkManager->deleteLater(); }; void CStackingDlg::retrieveLatestVersionInfo() { #ifndef DSSBETA ZFUNCTRACE_RUNTIME(); QSettings settings; bool checkVersion = settings.value("InternetCheck", false).toBool(); if (checkVersion) { networkManager = new QNetworkAccessManager(); QObject::connect(networkManager, &QNetworkAccessManager::finished, [this](QNetworkReply * reply) { this->versionInfoReceived(reply); }); networkManager->get(QNetworkRequest(QUrl("http://deepskystacker.free.fr/download/CurrentVersion.txt"))); } #endif }
Please note the CStackingDlg is not derived from QObject but from CDialog (MFC) so I can't rely on QObject as parent to delete stuff.
David
-
@mrjj said in QNetworkAccessManager at global scope:
Is static safe within a function in relation not being initialized before QApplication?
A local static is initialized when the function is first called. Since c++11 the creation of the local static is even thread-safe (as long as it's a object, not a pointer)