Quand tu affecte 'Nothing' à un objet, tu ne détruit pas uniquement les liens vers ce dernier mais tu le kill totalement de la mémoire. C'est le seul moyen de détruire un objet en mémoire.
================
Site Web de JDPROGPrésentation de MP3 Index
Logiciel d'indexation de fichier MP3
[ Lien ]-------------------------------
Réponse au message :
-------------------------------
> Salut,
>
> J'aimerais connaitre la méthode à suivre pour effacer proprement une collection d'objets de la mémoire sans se contenter de simplement supprimer la référence d'accès.
> Désolé, ça va être un peu long mais cela vous permettra de critiquer mon code par la même occasion.
>
> Je m'explique : J'ai une structure (disons typBiblio) contenant une collection d'objets A (pour imager disons que A est une étagère). Chaque objet A contenant lui-même une collection d'objets B (disons que B est un livre). Comme il y a plusieurs collections d'étagères, il existe un tableau de typBiblio (tabBiblios(n)). Ces objets (A et B - Etagères et Livres) sont créés par l'utilisateur durant l'execution de l'application. Et je veux pouvoir effacer tous les objets existants pour tout remmettre à zéro.
>
> Schéma de principe :
>
>
> tabBiblios(1) > -> Numero > -> Libelle > -> Etageres > -> 1ere Etagere > -> Livres > -> Livre 1 > -> Livre 2 > -> Livre 3 > -> 2eme Etagere > -> Livres > -> Livre 1 > -> Livre 2 > -> ... > -> ... > tabBiblios(2) > -> Numero > -> Libelle > -> Etageres > -> 1ere Etagere > -> Livres > -> Livre 1 > -> Livre 2 > -> Livre 3 > -> 2eme Etagere > -> Livres > -> Livre 1 > -> Livre 2 > -> ... > -> ... > etc... > |
>
>
> Détail (Les livres et étagères étant une image pour mieux comprendre, les noms ont été changé et les propriétés de mes classes n'ont aucun lien avec des livres ou des étagère) :
>
> public type typBiblio > Numero As Integer > Libelle As String > Etageres As New clsEtageres 'Collection d'étagères > End Type > > dim tabBiblios(NbEtageres) as typBiblio > > > la classe d'un "livre" (clsLivre) : Code: > Option Explicit > Public Code As String > Public Libelle As String > Public Start As String > Public ImgID As String > > Et une classe "collection de livres" (clsLivres) pour gérer les livres : Code: > Option Explicit > > 'variable locale pour la collection > Private colObjets As Collection > > Public Function Add(ByVal strCode As String, ByVal strLibelle As String, _ > ByVal strStart As String) As clsLivre > > 'Création de l'objet Livre > Dim LivreNew As New clsLivre > 'définir les propriétés passées à la méthode > With LivreNew > .Code = strCode > .Libelle = strLibelle > .Start = strStart > .ImgID = Left(strCode, 2) & "-" & Right(strCode, 3) > End With > > 'Ajout à la collection > colObjets.Add LivreNew, strCode > > Set Add = LivreNew > Set LivreNew = Nothing > End Function > > Public Sub Delete(ByVal Index As Variant) > 'utilisée lors de la suppression d'un élément de la collection > 'Index contient l'index ou la clé, il est donc > 'déclaré en tant que Variant > 'Syntaxe: x.Remove(xyz) ou x.Remove(5) > colObjets.Remove (Index) > End Sub > > Public Property Get Item(ByVal Index As Variant) As clsLivre > 'Utilisé pour référencer un élément dans la collection > 'Index contient l'index ou la clé dans la collection > 'Il est donc déclaré en tant que Variant > 'Syntaxe: Set toto = x.Item(xyz) ou Set toto = x.Item(5) > Set Item = colObjets(Index) > End Property > > Public Property Get Count() As Integer > 'utilisée pour lire le nombre d'éléments dans la > 'collection. Syntaxe: Debug.Print x.Count > Count = colObjets.Count > End Property > > Public Function NewEnum() As IUnknown > 'Cette propriété vous permet d'énumérer > 'cette collection avec la syntaxe For...Each > Set NewEnum = colObjets.[_NewEnum] > End Function > > Public Function Exist(ByVal strCode As String) As Boolean > 'Cette fonction teste l'existence d'un Livre dans la collection > 'Elle retourne vrai ou faux selon le résultat > On Error GoTo Err > Dim LivreTemp As clsLivre > > Set LivreTemp = colObjets(strCode) > Exist = True > Exit Function > > Err: > Exist = False > End Function > > Private Sub Class_Initialize() > 'Crée la collection lorsque cette classe est créée > Set colObjets = New Collection > End Sub > > Private Sub Class_Terminate() > 'Détruit la collection lorsque cette classe est détruite > Set colObjets = Nothing > End Sub > |
>
> J'ai également une classe d'"étagère" (clsEtagere) possédant une collection de livres (clsLivres) :
>
> Option Explicit > > Public Start As String > Public Index As Integer > Private mLivres As New clsLivres 'Collection de Livres > > Public Property Get Livres() As clsLivres > Set Livres = mLivres > End Property > > Et donc la classe "collection d'étagères" pour gérer les étagères (clsEtageres) : Code: > Option Explicit > > 'variable locale pour la collection > Private colObjets As Collection > 'variable locale pour le compteur d'étagères > Private intCompteur As Integer > > Public Function Add(ByVal strStart As String) As clsEtagere > intCompteur = intCompteur + 1 > 'Création de l'évènement > Dim EtagereNew As New clsEtagere > 'définir les propriétés passées à la méthode > With EtagereNew > .Start = strStart > .Index = intCompteur > End With > > 'Ajout à la collection > Set Add = EtagereNew > Set EtagereNew = Nothing > End Function > > Public Sub Delete(ByVal Index As Integer) > 'utilisée lors de la suppression d'un élément de la collection > 'Index contient l'index qui correspond à la clé > colObjets.Remove CStr(Index) > End Sub > > Public Property Get Item(ByVal Index As Integer) As clsEtagere > 'Utilisé pour référencer un élément dans la collection > 'Index contient l'index qui correspond à la clé > Set Item = colObjets(CStr(Index)) > End Property > > Public Property Get Count() As Integer > 'utilisée pour lire le nombre d'éléments dans la > 'collection. Syntaxe: Debug.Print x.Count > Count = colObjets.Count > End Property > > Public Function NewEnum() As IUnknown > 'Cette propriété vous permet d'énumérer > 'cette collection avec la syntaxe For...Each > Set NewEnum = colObjets.[_NewEnum] > End Function > > Private Sub Class_Initialize() > 'Crée la collection lorsque cette classe est créée > Set colObjets = New Collection > End Sub > > Private Sub Class_Terminate() > 'Détruit la collection lorsque cette classe est détruite > Set colObjets = Nothing > End Sub > > Public Function Exist(ByVal Index As Integer) As Boolean > 'Cette fonction teste l'existence d'une Etagere dans la collection > 'Elle retourne vrai ou faux selon le résultat > On Error GoTo Err > Dim EtagereTemp As clsEtagere > > Set EtagereTemp = colObjets(CStr(Index)) > Exist = True > Exit Function > > Err: > Exist = False > For Each EtagereTemp In colObjets > MsgBox EtagereTemp.Index & " - " & EtagereTemp.Start > Next > End Function > |
>
> Bon voila pour la description. Ouf !
>
> Passons maintenant au problème. Pour effacer tous les objets, j'ai pensé qu'il fallait des "deleter" un par un, en commencant par effacer tous les livres d'une étagère avant d'effacer l'étagère elle-même :
> Public Sub DetruireAll() > Dim i As Integer, j As Integer, k As Integer > Dim Nb1 As Integer, Nb2 As Integer > Dim DelEtagere As clsEtagere > Dim DelLivre As clsLivre > > For i = 1 To NbEtageres > 'Destruction des Livres > For Each DelEtagere In tabBiblio(i).Etageres > With DelEtagere.Livres > Nb2 = .Count > For k = 1 To Nb2 > .Delete (1) 'J'ai aussi essayé avec (k) > Next k > End With > Next DelEtagere > 'Destruction des Etagères > Nb1 = tabBiblio(i).Etageres.Count > For j = 1 To Nb1 > tabBiblio(i).Etageres.Delete (j) > Next j > 'effacement des données de la biblio > tabBiblio(i).Numero=0 > tabBiblio(i).Libelle = "" > Next i > End Sub > Là j'obtient des erreurs d'index inexistants lors des méthodes "Delete" ??? > |
>
> J'ai donc opté pour cette solution :
>