Qt deletelater函数分析(1)

                      生活的全部意义在于无穷地探索尚未知道的东西,在于不断地增加更多的知识。——左拉


该函数是QObject类的函数:                             --------------------------       (了解该类可以帮助深刻理解即Qt)

deletelater的原理是 QObject::deleteLater()并没有将对象立即销毁,而是向主消息循环发送了一个event,下一次主消息循环收到这个event之后才会销毁对象。

所有继承自QObejet类的类都会维护一个自己的子对象列表,同时会存储自己的父对象,所以界面中的各个控件(各个控价的基类都是QObject)可以实现层次!


“当我们使用父对象来创建一个对象的时候 ,父对象会把这个对象添加到自己的子对象列表中。当这个父对象被删除的时候,它会遍历它的子对象类表并且删除每一个子对象,然后子对象们自己再删除它们自己的子对象,这样递归调用直到所有对象都被删除。 这种父子对象机制会在很大程度上简化我们的内存管理工作,减少内存泄露的风险。所以,使用deleteLater主要作用还是减少内存泄露的风险。”

关闭一个窗口时(QQuickView, QQuickWindow,注意QQuickView的基类是QQuickWindow),建议用这个方法的deleteLater()


项目中的实例:

QQuickView* view = new QQuickView();

view->setSource(QUrl(QStringLiteral("qrc:/QML/xxx.qml")));

view->show();

关闭view时:

view->close(); //该函数会偶尔导致整个程序退出!看后面分析。可以不用它,直接掉deletelater()

view->deleteLater()

view = NULL;

调用deleteLater()后,xxx.qml中定义的对象会被销毁(析构函数被调用)。close函数仅仅是关闭页面,并不会将内存释放掉,如果不调用deleteLater函数会导致内存占用不断增加! 我在调试过程中,快速点击新建和关闭,并没有遇到deleteLater函数调用不及时的问题。

 

上面调用的close函数是QquickView的基类QWindow的函数,帮助文档中的解释:

“potentially quitting the application!!!!!!!!!!”---所以还是别用了


# 注意:

view->deleteLater()被调用之后需要将view这个指针置为NULL,否则就是野指针。

疑惑:如果按照上面的代码所写,会不会出现这种情况:当删除事件加入循环队列后,指针被赋值为0,接着删除事件被处理,这时因为指针为0,所以堆对象删除失败,造成了内存泄露?---- 不是! 

deleteLater函数是QObject类的一个成员函数,它发出一个event给主循环,发出的事件中本身包含了需要被delete的对象的地址。

Ref:

https://www.cnblogs.com/liushui-sky/p/5852090.html https://blog.csdn.net/qq_30126571/article/details/78036576 https://blog.csdn.net/ZXHL_hxf/article/details/83410852 https://blog.csdn.net/li235456789/article/details/50599757 https://bbs.csdn.net/topics/392388844 https://blog.csdn.net/dbzhang800/article/details/6300025

posted @ 2019-01-17 21:46  JadeCicada  阅读(6332)  评论(0编辑  收藏  举报