Es gibt ein Objekt der Klasse QNetworkReply. Es gibt einen Slot (in einem anderen Objekt), der mit seinem finished()-Signal verbunden ist. Die Signale sind synchron (die Standardsignale). Es gibt nur einen Thread.
Irgendwann möchte ich die beiden Objekte loswerden. Keine Signale oder irgendetwas mehr von ihnen. Ich will sie loswerden. Nun, ich dachte, ich benutze
delete obj1; delete obj2;
Aber kann ich das wirklich? Die Spezifikationen für ~QObject sagen:
Das Löschen eines QObjects, während anstehende Ereignisse darauf warten, zugestellt zu werden, kann einen Absturz verursachen.
Was sind die "anstehenden Ereignisse"? Könnte das bedeuten, dass ich beim Aufrufen meiner delete
dass es bereits einige "ausstehende Ereignisse" gibt, die zugestellt werden müssen, und dass diese einen Absturz verursachen können, und ich kann nicht wirklich überprüfen, ob es welche gibt?
Sagen wir also, ich rufe an:
obj1->deleteLater(); obj2->deleteLater();
Um sicher zu gehen.
Aber bin ich wirklich sicher? Die deleteLater
fügt ein Ereignis hinzu, das in der Hauptschleife behandelt wird, wenn die Steuerung dort ankommt. Kann es einige anstehende Ereignisse (Signale) für obj1
o obj2
bereits vorhanden und warten darauf, in der Hauptschleife bearbeitet zu werden vor deleteLater gehandhabt wird? Das wäre sehr unglücklich. Ich möchte keinen Code schreiben, der auf den Status "etwas gelöscht" prüft und das eingehende Signal in allen meinen Slots ignoriert.
5 Stimmen
Sieht aus wie
obj->disconnect(); obj->deleteLater();
ist der richtige Weg:1 Stimmen
Nachdem ich den QObject-Quelltext gelesen habe, scheint es, dass
deleteLater()
stellt einfach eineQDeferredDeleteEvent
zu dem Objekt, dasdeleteLater()
wurde aufgerufen am. Wenn dieses Ereignis vom QObject empfangen wird, ruft sein Event-Handler schließlich reguläredelete
der wiederum den Destruktor des QObjects aufruft. Die Signaltrennung erfolgt erst am Ende des Destruktors, daher würde ich vermuten, dass das QObject Slots ausführen wird, die durch DirectConnection-Signale aufgerufen werden, die nach dem Aufruf vondeleteLater()
aber bevor die Ereignisschleife zurückkehrt.