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

125 lines
3.1 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#qt
### **背景**
deleteLater 是 [QObject](https://so.csdn.net/so/search?q=QObject&spm=1001.2101.3001.7020) 类对象的成员函数,用于延迟删除一个 QObject 类对象,且对 QObject 类对象的删除推荐使用 deleteLater 而非 delete 。
### **deleteLater**
####
**①.概述**
deleteLater 依赖于[事件循环](https://so.csdn.net/so/search?q=%E4%BA%8B%E4%BB%B6%E5%BE%AA%E7%8E%AF&spm=1001.2101.3001.7020),调用 deleteLater 后本质是发送了一个 DeferrerDelete 事件,在事件循环处理中把对象删除。
#### **②.代码示例**
``` cpp
demo = new QtClassDemo(this);
demo->deleteLater();
demo = nullptr;
```
![[Pasted image 20240806155949.png]]
### **deleteLater 和 delete**
####
deleteLater 会在当前对象的所有事件处理完成后再删除对象
``` cpp
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 则是立即删除对象,对象的既有事件不再处理
``` cpp
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 后依然可以访问和操作对象,直到再次回到事件循环
``` cpp
demo = new QtClassDemo(this);
demo->setObjectName("demo");
demo->deleteLater();
qDebug() << demo->objectName();
demo = nullptr;
```
![[Pasted image 20240806160032.png]]
### **deleteLater 和 QSharedPointer**
####
①.概述
[智能指针](https://so.csdn.net/so/search?q=%E6%99%BA%E8%83%BD%E6%8C%87%E9%92%88&spm=1001.2101.3001.7020)可以传入自定义的删除器,对于继承自 QObject 的类对象可以传入 deleteLater 。
#### ②.代码示例
``` cpp
QSharedPointer<QtClassDemo> demoClass(new QtClassDemo(this), &QObject::deleteLater);
```
 
###
**deleteLater 和 moveToThread**
####
①.概述
**moveToThread 的本质是把 QObject 对象的事件循环移动到子线程进行处理**
``` cpp
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 进行资源清理
``` cpp
//工作对象工作完成,停止线程
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 );
```