cs_Ricou13
Messages postés40Date d'inscriptionlundi 16 décembre 2002StatutMembreDernière intervention 8 septembre 2006
-
19 déc. 2002 à 07:18
cs_Ricou13
Messages postés40Date d'inscriptionlundi 16 décembre 2002StatutMembreDerniè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.
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.
cs_processus
Messages postés360Date d'inscriptionvendredi 24 août 2001StatutMembreDernière intervention 9 juillet 20083 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