我在這裏提出這個問題之前已經想了很多,並閱讀了很多文章。沒有一篇文章給了我一個正確的答案。QThread finished()連接到刪除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();
工對象具有新線程的親和性。
1>工人完成的信號將在線程上調用quit()。這將結束線程的事件循環並啓動線程完成信號。
2>工人完成信號連接到工人deleteLater()。根據deleteLater()文檔
**計劃此對象的刪除。 控件返回到事件循環時,該對象將被刪除。如果事件循環是>沒有運行
時調用此函數(例如deleteLater()被調用QCoreApplication之前 對象:: EXEC上()),對象將進行一次事件循環開始刪除 。
請注意,進入和離開新的事件循環(例如通過打開模式對話框)將不會執行延遲刪除操作;對於要刪除的對象,控件必須 返回調用deleteLater()的事件循環。
注意:它 可以安全地多次調用此函數;當交付了首遞延 刪除事件,對象任何未決事件 從事件隊列中刪除。**
所以在沒有事件循環,因爲線程已經退出,並已經提出了完成的信號,我們將不再再次啓動相同的線程。在這種情況下,deleteLater()永遠不會被處理,因爲事件循環不存在,並且worker對象根本不會被刪除。這是否會造成內存泄漏?
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
如果我們認爲交換兩條線可以解決問題,那麼我還有一個問題。 QT明確指出,信號發射時槽被調用的順序不確定
上面提到的文章鏈接中有很多評論。就連筆者沒能回答這個問題完全
不能刪除的工人所創建的對象的線程:後
run
返回源執行。因爲它已經使用moveToThread移動到線程。你能解釋一下嗎? – Srikan
另外我會建議分配一個父'QThread'。由於'QThread'的實例是它生成的線程的一部分(不同於任何移動到它或它的'run()'方法的對象),執行'thread = new QThread(this)是完全安全的。 '如果'線程'是其他類的一部分。一般來說,如果有更好的非手動解決方案,應該避免調用delete。即使在標準C++中,您也可以使用智能指針,而不需要手動清理肩膀的負擔。 – rbaleksandar