![]() |
TInterfacedObject wird nicht freigegeben
Hallo!
Ich habe das Problem, dass ich so wie es aussieht mal wieder über den Referenzzähler bei Interfaces stolpere. Ich habe eine Komponente basierend auf TWebbrowser, welche ein HTML-Editor sein soll. Im OnDocumentComplete-Handler erzeuge ich ein TInterfacedObject zum Handling von Javascript-Events (was soweit auch alles funktioniert). Das einzige Problem ist, dass dieses TInterfacedObject genau einmal weniger freigegeben als instantiiert wird und folglich ein Memleak beim Programmende entsteht. Hier erstmal ein bisschen Code:
Delphi-Quellcode:
Die Meldung von FastMM lautet, dass genau eine Instanz von THtmlEvent beim Programmende noch existierte und zwar egal wie viele Documents zwischendurch geladen und OnDocumentComplete aufgerufen wurde.
type
THTMLEditor = class(TWebbrowser) private { private declarations } FKeyDownEvent: THtmlEvent; {...} procedure THTMLEditor.DoDocumentComplete(ASender: TObject; const pDisp: IDispatch; const URL: OleVariant); begin GetDocument.body.style.borderStyle:= 'none'; if HasDocument then begin FKeyDownEvent:= NIL; // <-- Ruft THtmlEvent.Destroy TATSÄCHLICH auf FKeyDownEvent:= THtmlEvent.Create; FKeyDownEvent.OnEvent:= DoKeyDownEvent; FKeyDownEvent.Document:= GetDocument; GetDocument.onkeypress:= FKeyDownEvent as IDispatch; end; EditMode:= TRUE; end; {...} destructor THTMLEditor.Destroy; begin FKeyDownEvent:= NIL; // <-- Wird bei Programmende ausgeführt FBodyHtml.Free; FInterfaceContainer.Free; inherited; end; {...} type THtmlEvent = class(TInterfacedObject, IDispatch) {...} end; {...} destructor THtmlEvent.Destroy; // <-- Wird bei Programmende NICHT ausgeführt begin FDocument:= NIL; inherited Destroy; end; |
AW: TInterfacedObject wird nicht freigegeben
Delphi-Quellcode:
ist vom Typ
FKeyDownEvent
Delphi-Quellcode:
, richtig?
THtmlEvent
Die Referenzzählung geht aber nur, wenn du mit dem Interface arbeitest und nicht mit dem Objekt |
AW: TInterfacedObject wird nicht freigegeben
Beim IE (TWEbBrowser) ist es Normal das die Implementierung die MS gemacht hat es nicht so genau mit der Freigabe der Interfaces nimmt.
Ich muss öfter direkt mal _Release-Aufrufen damit mir der Speicher nicht volläuft. Vermutlich vergisst der IE auch bei dir auch die entsrpechenden Release-Aufrufe. |
AW: TInterfacedObject wird nicht freigegeben
Zitat:
|
AW: TInterfacedObject wird nicht freigegeben
Leider ist deine Annahme falsch
Delphi-Quellcode:
denn die Instanz wird freigegeben wegen
FKeyDownEvent:= NIL; // <-- Ruft THtmlEvent.Destroy TATSÄCHLICH auf
... GetDocument.onkeypress:= FKeyDownEvent as IDispatch;
Delphi-Quellcode:
GetDocument.onkeypress:= FKeyDownEvent as IDispatch;
|
AW: TInterfacedObject wird nicht freigegeben
Delphi-Quellcode:
var YourObject : ...;
if YourObject.Type.BeginsWith.I then YourObject:= nil; if YourObject.Type.BeginsWith.T then YourObject.Free; |
AW: TInterfacedObject wird nicht freigegeben
Zitat:
|
AW: TInterfacedObject wird nicht freigegeben
Zitat:
Delphi-Quellcode:
TMyClass = class( TInterfacedObject )
end; var MyInstance : TMyClass; MyInterface : IInterface; // das geht MyInstance := TMyClass.Create; MyInstance.Free; // das knallt MyInstance := TMyClass.Create; MyInterface := MyInstance; // Referenz-Zähler auf 1 MyInterface := nil; // Referenz-Zähler auf 0 => Instanz wird freigeben MyInstance.Free; // rumms |
AW: TInterfacedObject wird nicht freigegeben
Zitat:
|
AW: TInterfacedObject wird nicht freigegeben
Zitat:
|
AW: TInterfacedObject wird nicht freigegeben
Das "Schöne" ist ja, daß der XE3 Compiler das
Delphi-Quellcode:
bei einer Interfacevariable nicht bemängelt,
[weak]
er diese Variable aber dennoch nicht als Weak-Referenz behandelt. (also im Win32) Hatte mich schon so gefreut, als der Compiler das ohne zu Mucken kompilierte. :wall: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:32 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz