Effacer proprement une collection d'objets

cs_Ricou13 Messages postés 40 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 8 septembre 2006 - 19 déc. 2002 à 07:18
cs_Ricou13 Messages postés 40 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 8 septembre 2006 - 19 déc. 2002 à 19:46
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 :
</td></tr></table>
Public Sub DetruireAll()
Dim i As Integer

For i = 1 To NbEtageres
set tabBiblio(i).Etageres = Nothing
Next i
End Sub
</td></tr></table>
Ici, lorsque la collection d'étagères est détruite (mise à Nothing), la méthode "Terminate" de la classe Etageres est executée. Cette dernière met sa collection d'étagères à "Nothing". Ce qui déclenche la méthode "Terminate" de la classe Livres qui met, également, sa collection de livres à "Nothing".

A priori, cela semble correct mais que sont devenus les propriétés des livres et des étagères. Les objets sont-ils rééllement détruits ou est-ce simplement leur accès qui est perdu. Car, dans ce cas, la mémoire n'a pas été nettoyée corectement et je risque une saturation si j'effectue cette opération trop souvent. D'autant que l'utilisateur peut créer beaucoup de livres et d'étagère, sauvegarder le résultat dans un fichier, et tout effacer pour recommencer.

Merci

2 réponses

cs_processus Messages postés 360 Date d'inscription vendredi 24 août 2001 Statut Membre Dernière intervention 9 juillet 2008 3
19 déc. 2002 à 11:05
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 JDPROG
Présentation de MP3 Index
Logiciel d'indexation de fichier MP3
0
cs_Ricou13 Messages postés 40 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 8 septembre 2006
19 déc. 2002 à 19:46
Donc le fait de définir à "Nothing" une collection d'objets contenants eux-même une collection d'autres objets est suffisant ?

Donc le fait de mettre à "Nothing" les collections des premiers objets (étagères) dans la méthode terminate, n'est pas necessaire ?
0
Rejoignez-nous