obsidian/笔记文件/2.笔记/Qt 中 deleteLater 使用总结.md
2025-03-26 00:02:56 +08:00

3.1 KiB
Raw Permalink Blame History

#qt

背景

deleteLater 是 QObject 类对象的成员函数,用于延迟删除一个 QObject 类对象,且对 QObject 类对象的删除推荐使用 deleteLater 而非 delete 。

deleteLater

①.概述

deleteLater 依赖于事件循环,调用 deleteLater 后本质是发送了一个 DeferrerDelete 事件,在事件循环处理中把对象删除。

②.代码示例

demo = new QtClassDemo(this);  
demo->deleteLater();  
demo = nullptr;

!Pasted image 20240806155949.png

deleteLater 和 delete

deleteLater 会在当前对象的所有事件处理完成后再删除对象

demo = new QtClassDemo(this);  
demo->setObjectName("demo");

qApp->postEvent(demo, new CustomEvent("hello"));  
qApp->postEvent(demo, new CustomEvent("world"));

demo->deleteLater();  
demo = nullptr;

!Pasted image 20240806160009.png

delete 则是立即删除对象,对象的既有事件不再处理

demo = new QtClassDemo(this);  
demo->setObjectName("demo");

qApp->postEvent(demo, new CustomEvent("hello"));  
qApp->postEvent(demo, new CustomEvent("world"));

delete demo;  
demo = nullptr;

!Pasted image 20240806160020.png

deleteLater 后依然可以访问和操作对象,直到再次回到事件循环

demo = new QtClassDemo(this);  
demo->setObjectName("demo");

demo->deleteLater();

qDebug() << demo->objectName();  
demo = nullptr;

!Pasted image 20240806160032.png

deleteLater 和 QSharedPointer

①.概述

智能指针可以传入自定义的删除器,对于继承自 QObject 的类对象可以传入 deleteLater 。

②.代码示例

QSharedPointer<QtClassDemo> demoClass(new QtClassDemo(this), &QObject::deleteLater);  

 

deleteLater 和 moveToThread

①.概述

moveToThread 的本质是把 QObject 对象的事件循环移动到子线程进行处理

qDebug() << "主线程:"<< QThread::currentThread();  
QThread * workThread = new QThread;

demo = new QtClassDemo(nullptr);  
demo->setObjectName("demo");  
demo->moveToThread(workThread);  
workThread->start();

bool QtClassDemo::event(QEvent * event)  
{  
  qDebug() << "事件处理线程:"<< QThread::currentThread() << event->type();

  return QObject::event(event);  
}

!Pasted image 20240806160059.png

②.利用 deleteLater 进行资源清理

//工作对象工作完成,停止线程  
QObject::connect(workObject,&WorkObject::workFinished,[&](){  
    workThread->quit();  
    workThread->wait();  
});  
//工作线程停止,删除工作对象  
QObject::connect(workThread,&QThread::finished,workObject,&WorkObject::deleteLater );  
//工作对象销毁,删除工作线程  
QObject::connect(workObject,&WorkObject::destroyed,workThread,&QThread::deleteLater );