Ceux qui utilisent les interfaces avec des objets dérivant de TinterfacedObject
peuvent ainsi apprécier le ref-count ou pas .
Imaginons que nous soignons dans un arbre. L'un des parents de cet arbre est manipulé par le biais d'une interface lors d'un traitement et possède une référence stockée dans ses enfants sous forme d'interface. Imaginons que ce parent se retrouve ne plus être utilisé par ses parents et par le programme, il devrait se libérer automatiquement. Sauf que ses enfants continuent à garder une référence de lui. Là vous avez une fuite mémoire. Pour ce faire il serait bien d'avoir un objet qui puisse stocker une interface sans pour autant incrémenter le ref-count de l'objet qui est stocké( référence faible comme dans le controller des TAggregatedObject). Pour ce faire je propose ceci :
Exemple d'utilisation :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83 unit interf_InterfaceFaible; interface type // l'interface faible permet de stocker une interface sans la notion de ref count ( idéal pour éliminer les références circulaires // Attention ne pas faire IInterface(aInterfaceFaible) mais aInterface := aInterfaceFaible ; // aInterfaceFaible := aInterface ; Rq: IInterfaceFaible(aInterface) fonctionne mais je vois pas à quoi ça peut servir // une fonction demandant en paramètre une IInterface ne peut recevoir directement un IInterfaceFaible il faut le convertir avant // le support à été surchargé exprès support( aInterfaceFaible, ITruc, aTruc ) ; // aInterfaceFaible := function_retournent_une_IInterface() ;à ne pas faire. IInterfaceFaible = record private FInterface: Pointer; procedure SetInterface( aInterface : IInterface ) ; function GetInterface() : IInterface ; property m_Interface : IInterface read GetInterface write SetInterface ; public class operator Implicit( a : IInterface ) : IInterfaceFaible ; overload; class operator Implicit( a : IInterfaceFaible ) : IInterface ; overload; end; function Supports(const Instance: IInterfaceFaible; const IID: TGUID; out Intf): Boolean; overload; implementation function Supports(const Instance: IInterfaceFaible; const IID: TGUID; out Intf): Boolean; var aInt : IInterface ; begin aInt := Instance ; Result := (aInt <> nil) and (aInt.QueryInterface(IID, Intf) = 0); end; //////////////////////////// { IInterfaceFaible } function IInterfaceFaible.GetInterface: IInterface; begin result := IInterface(FInterface) ; end; //////////////////////////// procedure IInterfaceFaible.SetInterface(aInterface: IInterface); begin FInterface := Pointer(aInterface) ; end; //////////////////////////// class operator IInterfaceFaible.Implicit( a : IInterface ) : IInterfaceFaible ; var aIntfFaible : IInterfaceFaible ; begin aIntfFaible.m_Interface := a ; result := aIntfFaible ; end; //////////////////////////// class operator IInterfaceFaible.Implicit( a : IInterfaceFaible ) : IInterface ; begin result := a.m_Interface ; end; //////////////////////////// end.
J'ai voulu que ça soit asse transparent qu'on est pas à créer cet objet où d'avoir un Pointer qui se balade alors qu'il contient une interface.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 var aTest : IInterfaceFaible ; aInt : ITruc ; begin aInt := TTruc.Create ; aTest := aInt ; aInt := nil ; // la ça se libère car aTest est une référence faible end;
Voila je voulais vous en faire part et avoir votre avis sur cette méthode .
(l'implements n'a cas bien se tenir )
Partager