Il y a un objet de classe QNetworkReply. Il y a un slot (dans un autre objet) connecté à son signal finished(). Les signaux sont synchrones (ceux par défaut). Il n'y a qu'un seul fil.
À un moment donné, je veux me débarrasser des deux objets. Plus de signaux ou quoi que ce soit venant d'eux. Je veux les faire disparaître. Eh bien, je pensais, j'utiliserai
delete obj1; delete obj2;
Mais est-ce que je peux vraiment le faire? Les spécifications de ~QObject disent :
Supprimer un QObject alors que des événements sont en attente de traitement peut provoquer un crash.
Quels sont les 'événements en attente'? Est-ce que cela signifie que pendant que j'appelle mon delete
, il y a déjà des 'événements en attente' à traiter et qu'ils pourraient causer un crash et je ne peux pas vraiment vérifier s'il y en a?
Donc disons que j'appelle :
obj1->deleteLater(); obj2->deleteLater();
Pour être sûre.
Mais, suis-je vraiment en sécurité? Le deleteLater
ajoute un événement qui sera géré dans la boucle principale lorsque le contrôle arrivera là. Est-ce qu'il peut y avoir des événements en attente (signaux) pour obj1
ou obj2
déjà là, attendant d'être traités dans la boucle principale avant que deleteLater ne soit traité? Ce serait très malheureux. Je ne veux pas écrire du code vérifiant l'état 'quelque peu supprimé' et ignorant le signal entrant dans tous mes slots.
4 votes
Il semble que
obj->disconnect(); obj->deleteLater();
soit la bonne solution :1 votes
Ayant lu la source QObject, il semble que
deleteLater()
se contente d'envoyer unQDeferredDeleteEvent
à l'objet sur lequeldeleteLater()
a été invoqué. Lorsque cet événement est reçu par le QObject, son gestionnaire d'événements invoquera ultimementdelete
régulier qui à son tour appelle le destructeur du QObject. La déconnexion du signal ne se produit qu'à la fin du destructeur, donc je suppose que le QObject exécutera des slots qui sont invoqués par des signaux de type DirectConnection qui sont émis après l'appel àdeleteLater()
mais avant que la boucle d'événements ne se termine.