Bug with `findChildren()` and `deleteLater()` causes crash
-
I query some components from the UI sometimes using
findChildren()and call their methods usingQMetaObject::invokeMethod(). This works fine.However, sometimes, some of these components are deleted using
deleteLater(), and these "deleted" components are still returned whenfindChildren()is called again. Then I suspect this is causingQMetaObject::invokeMethod()to crash (according to debugger, it crashes on this function, even usingtry/catch(...)block).This issue is random because
deleteLater()just sometimes takes a long time to remove the components, and in this while, I might have thefindChildren()called, and there is no way I see to prevent the crash.Any idea how to prevent
QMetaObject::invokeMethod()from crashing the application? -
I query some components from the UI sometimes using
findChildren()and call their methods usingQMetaObject::invokeMethod(). This works fine.However, sometimes, some of these components are deleted using
deleteLater(), and these "deleted" components are still returned whenfindChildren()is called again. Then I suspect this is causingQMetaObject::invokeMethod()to crash (according to debugger, it crashes on this function, even usingtry/catch(...)block).This issue is random because
deleteLater()just sometimes takes a long time to remove the components, and in this while, I might have thefindChildren()called, and there is no way I see to prevent the crash.Any idea how to prevent
QMetaObject::invokeMethod()from crashing the application?@Developer123
Until you get a better answer, mine would be "no". It's up to you not to call things on objects once you have calleddeleteLater()on them,findChildren()won't check.I don't think you/Qt can tell there is a pending
deleteLater()on an object. The code for that is simply:void QObject::deleteLater() { QCoreApplication::postEvent(this, new QDeferredDeleteEvent()); }If you are in charge of the code which calls
deleteLater()on an object in a children tree you might remove the object from the tree yourself at that point to prevent it being found.Be aware that whenever Qt deletes a
QObjectthat emits adestroyed()signal. If you really have to cope with the situation you might be able to attach a slot to that which then notes that no further calls must be made on this object, but it's messy/may not work as you need. -
@Developer123
Until you get a better answer, mine would be "no". It's up to you not to call things on objects once you have calleddeleteLater()on them,findChildren()won't check.I don't think you/Qt can tell there is a pending
deleteLater()on an object. The code for that is simply:void QObject::deleteLater() { QCoreApplication::postEvent(this, new QDeferredDeleteEvent()); }If you are in charge of the code which calls
deleteLater()on an object in a children tree you might remove the object from the tree yourself at that point to prevent it being found.Be aware that whenever Qt deletes a
QObjectthat emits adestroyed()signal. If you really have to cope with the situation you might be able to attach a slot to that which then notes that no further calls must be made on this object, but it's messy/may not work as you need.... or don't use deleteLater() for those objects.