![]() |
Interfacelisten: Objekt wird bei remove freigegeben
Folgender Code:
Delphi-Quellcode:
Kann mir jemand erklären, was ich falsch mache bzw. wo mein Denkfehler liegt?
Type
TTest = Class (TInterfacedObject, IInterface) End; procedure TForm1.Button1Click(Sender: TObject); Var l : TInterfaceList; x : TTest; begin l := TInterfaceList.Create; x := TTest.Create; l.Add(x); L.Remove(x); x.free; // <<--- Peng. X ist schon freigeben. Wieso? l.free; end; Ich müsste doch jedes Objekt selbst wieder freigeben, was ich per Create erzeuge, oder nicht? |
Re: Interfacelisten: Objekt wird bei remove freigegeben
sowas passiert halt, wenn man Interfaces und Objekte mischt :warn:
also Objekt hat es einen Instanzzähler von 0, bei übergabe an die Interface-Variable/-Liste wird dieser auf 1 erhöht und beim löschen/remove wieder auf 0 erniedrigt und demnach freigegeben. |
Re: Interfacelisten: Objekt wird bei remove freigegeben
Die TInterfaceList ist eine Liste von Interfaces (soweit bist du wahrscheinlich schon gekommen :mrgreen: ).
Beim .Add holt sie sich eine Referenz auf das übergebene Interface -> AddRef, Referenzzähler 1. Beim .Remove verliert sie die Reference -> Release, Referenzzähler 0, Freigabe des Objekts. Wie sonst auch gilt also auch hier die Regel: Interfaces und Klassen sind nur mit viel Umsicht zu vermischen. Und bei Interfaces gilt eben nicht, dass du alles mit Free freigeben musst, was du mit Create angefordert hast. |
Re: Interfacelisten: Objekt wird bei remove freigegeben
|
Re: Interfacelisten: Objekt wird bei remove freigegeben
Zitat:
Mir war das mit dem Referenzzähler auch klar, ich habe nämlich entdeckt, das ich mit meinem RAD auch debuggen kann. :thumb: Die Frage ist nur, wieso ist das so implementiert? In meinen Augen ist das eine ziemliche Einschränkung der Sprache "Delphi", aber damit muss ich halt leben. |
Re: Interfacelisten: Objekt wird bei remove freigegeben
Das ist schon OK und auch vollkommen richtig so. :angel:
Wenn du es mischen willst, dann bleiben dir grundsätzlich 2 Möglichkeiten_ - entweder du schaltest die Referenzzählung ab und gibst selber frei, mußt dann aber auch aufpassen, daß beim Freigeben das Objetzt nicht doch nocht irgendwo benötigt wird, weil z.B. irgendwo eine Intervace-Variable noch nicht freigegeben wurde - oder du sagst, daß du gern eine Instanz für deine Objektbehandlung hättest
Delphi-Quellcode:
l := TInterfaceList.Create;
x := TTest.Create; x._AddRef; l.Add(x); L.Remove(x); x._Release; l.Free; |
Re: Interfacelisten: Objekt wird bei remove freigegeben
Grundregel, wenn du nicht die Referenzzählung außer Kraft setzen oder anderweitig "austricksen" willst: niemals mit Objektreferenzen sondern immer mit Interfacereferenzen arbeiten, wenn dir die Referenzzählung keinen Strich durch die Rechnung machen soll
|
Re: Interfacelisten: Objekt wird bei remove freigegeben
@himitsu: Auch hier gibst du durch das abschließende _Release das Objekt schon frei.
Edit: Hoppla, zu früh geschrien. Das ist ja ein l.Free am Ende. :oops: |
Re: Interfacelisten: Objekt wird bei remove freigegeben
Zitat:
abgesehn, daß _Release das Objekt nicht freigibt, wenn noch irgendwo eine Referenz existiert und durch _AddRef die InterfaceList das Objekt auch nicht freigibt, da ja der Referenzzähler danach nur von 2 auf 1 fällt und demnach nicht freigegeben wird. |
Re: Interfacelisten: Objekt wird bei remove freigegeben
Zitat:
Also statt
Delphi-Quellcode:
einfach bei den Typen öfter ein I statt eines T verwenden:
var
L: TInterfaceList; X: TTest;
Delphi-Quellcode:
var
L: IInterfaceList; X: IMyInterface; Manche Bibliotheken funktionieren sogar besser, wenn für die Erzeugung von Instanzen Interface-Variablen benutzt werden. Zum Beispiel kann es leicht zu Access Violations geben, wenn man für eine dynamisch erzeugte TXMLDocument Instanz den Variablentyp IXMLDocument (statt TXMLDocument) benutzt. (siehe ![]() Cheers, |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:43 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-2025 by Thomas Breitkreuz