Qt类QNetworkAccessManager内存增长问题解决

qt版本5.4

项目在使用qt中QNetworkAccessManager进行网络通信时发现内存不停的增长,我当然知道每次new后都需要deleteLater来释放,但是这个操作在高频率时是没有用的(控制权很难回到QApplication对象上,一直在做逻辑操作,QApplication对象没有机会去释放队列里面的内容),deleteLater原理请自行百度;

QNetworkAccessManager其实是用线程来访问网络的,deleteLater释放貌似在线程结束前?所以deleteLater不执行,线程一直不结束,内存被占用(如果错误请网友指正,以免坑人)

怎么解决呢?先看官方代码片段

片段1
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)),
        this, SLOT(replyFinished(QNetworkReply*)));

manager->get(QNetworkRequest(QUrl("http://qt-project.org")));

片段2
QNetworkRequest request;
request.setUrl(QUrl("http://qt-project.org"));
request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");

QNetworkReply *reply = manager->get(request);
connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
        this, SLOT(slotError(QNetworkReply::NetworkError)));
connect(reply, SIGNAL(sslErrors(QList)),
        this, SLOT(slotSslErrors(QList)));

通过代码片段分析结合实际操作得出几个需要注意的地方

  • new时要指定父对象为this;
  • finished对应的槽函数需要设置接收QNetworkReply指针;
  • get请求返回的指针和SLOT(replyFinished(QNetworkReply*))槽函数中的指针指向的是同一地方,如果在槽函数中已经执行过reply->deleteLater();就不需要在主函数内再执行了
  • 槽函数绑定对象 SLOT(slotReadyRead_Get())中用QByteArray readbyte = m_Reply->readAll(); pdownloadfile->write(readbyte);的方式写数据到文件,不要直接用 pdownloadfile->write(m_Reply->readAll());这样写文件是错误的(当然如果你只是读数据那么是没有问题的吧

内存增长的解决方法

replyFinished_Get(QNetworkReply *reply)中一定要记得reply->deleteLater();

QNetworkAccessManager对象定义为类成员或者全局指针,在初始化时进行new QNetworkAccessManager(this);不要在每次需要用的时候new!!!不要在每次需要用的时候new!!!不要在每次需要用的时候new!!!

提示

每次new QNetworkAccessManager的对象你都要做好它不会在程序运行中被释放的心里准备,即便你调用了deleteLater,忙碌的 QApplication也不一定鸟你

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(编程)