Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QTimer::SingleShot fired after object is deleted

// Example class
class A : public QObject
{
   Q_OBJECT
   void fun() {
       Timer::SingleShot(10, timerSlot); //rough code
   }
   public slot:
   void timerSlot();
}

auto a = SharedPointer<A>(new A);
a->fun();
a->reset(); // a deleted

In this case after a is deleted and timer is fired, would it execute timerSlot()? I'm getting an extremely rare crash and not sure if it's because of something fishy in this logic.

like image 346
JamesWebbTelescopeAlien Avatar asked Jun 17 '16 01:06

JamesWebbTelescopeAlien


2 Answers

Even if the timer fires, it won't trigger the slot. The docs of ~QObject state: All signals to and from the object are automatically disconnected, and any pending posted events for the object are removed from the event queue. The only way you can trigger the A::timerSlot and delete A at the same time is if you use threads.

like image 191
thuga Avatar answered Oct 19 '22 23:10

thuga


You are not obligated to disconnect an object's signals and slots before deleting it.

The QObject destructor will clean up obsolete signal-slot connection for you, as long as you:

  1. Inherit from QObject

  2. Use the Q_OBJECT macro in your class definition

Following these conventions ensures that your object emits a destroyed() signal when deleted. That's actually what Qt's signals-and-slots system uses to clean up dangling references.

You can listen to the destroyed() signal yourself if you'd like to add some debugging code to track object lifecycles.

(Depending on the particular version of Qt/moc you are using, it's quite possible that code with a non-QObject using slots, or a QObject-derived class that doesn't have Q_OBJECT in its header will still compile but cause the timerSlot() method to be invoked on a garbage pointer at runtime.)

like image 23
Alex P Avatar answered Oct 19 '22 22:10

Alex P