Sri*_*kan 7 signals quit qthread qobject
在这里提出这个问题之前,我已经想了很多并阅读了很多文章.这些文章都没有给我一个正确的答案.
http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
QThread* thread = new QThread;
Worker* worker = new Worker();
worker->moveToThread(thread);
connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
Run Code Online (Sandbox Code Playgroud)
Worker对象具有新线程的亲和力.
1> Worker完成信号将调用线程上的quit().这将结束线程的事件循环并启动线程完成信号.
2> Worker完成信号连接到worker deleteLater().根据deleteLater()文档
**安排此对象删除.当控制返回到事件循环时,将删除该对象.如果事件循环>未运行
当调用此函数时(例如,在QCoreApplication :: exec()之前在对象上调用deleteLater()),一旦启动事件循环,该对象将被删除.
注意,进入和离开新的事件循环(例如,通过打开模态对话框)将不执行延迟删除; 对于要删除的对象,控件必须返回到调用deleteLater()的事件循环.
注意:不止一次调用此函数是安全的; 在传递第一个延迟删除事件时,将从事件队列中删除该对象的任何挂起事件.**
因此,当没有eventloop时,由于线程已经退出并且它已经提升了完成的信号,我们将不再再次启动相同的线程.在这种情况下,将永远不会处理deleteLater(),因为事件循环不存在,并且根本不会删除worker对象.这不会造成内存泄漏吗?
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
Run Code Online (Sandbox Code Playgroud)
如果我们认为交换这两行将解决问题,那么我还有另外一个问题.QT明确指出,在发出信号时调用插槽的顺序是不确定的
上面提到的文章链接中有很多评论.即便是作者也无法完全回答这个问题
QThread在发送完成信号后将执行QCoreApplication::sendPostedEvents事件类型为 QEvent::DeferredDelete
换句话说,QThread将收集所有挂起的deleteLaters并在run返回后执行它们