![]() |
Classes/Interfaces, Reference counting, wann/wie
Hallo,
ich verstehe es nicht ganz, wann das Reference-Counting der Interfaces genutzt wird. Also, Beispiel:
Code:
Kann mir jemand erklären, wann das Reference-Counting genutzt wird?
ITest = interface(IInterface)
procedure CallInterface(testObject: ITest); end; TTest = class(TInterfacedObject, ITest) public procedure CallInterface(testObject: ITest); procedure CallInstance(testObject: TTest); end; procedure TForm1.Test(); var testInterface: ITest; testInstance: TTest; begin // Funktioniert. testInstance := TTest.Create; testInstance.CallInstance(testInstance); testInstance.Free; // Interface wirft Fehler, obwohl immer nach TTest gecastet wird testInterface := TTest.Create; (testInterface as TTest).CallInstance(testInterface as TTest); (testInterface as TTest).Free; // Fehler // auch wenn ich mit einer Klasseninstanz arbeite, diese aber an eine Funktion übergeben, die das Interface erwartet, gibt es Fehler. // Es wird doch kein neues Objekt erzeugt, sondern nur die Referenz an die Funktion übergeben testInstance := TTest.Create; testInstance.CallInterface(testInstance); testInstance.Free; // Fehler end; |
AW: Classes/Interfaces, Reference counting, wann/wie
Der Thread hier und der verlinkte Artikel bringen vielleicht etwas Licht ins Dunkel:
![]() Ggf. für den Einstieg: ![]() |
AW: Classes/Interfaces, Reference counting, wann/wie
Es macht keinen Sinn sich so etwas anzutun. In einem Satz: Entweder du referenzierst etwas via Interface und nutzt ARC, oder man referenziert es über Klassentypen und nutzt manuelle Speicherverwaltung.
Schau doch im Debugger einfach mal was genau
Delphi-Quellcode:
hier der "Fehler" ist: Hier wirft die Delphi-Bibliothek selbst einen Fehler und meint "Hey Moment, das kann doch überhaupt nicht sein! Es bestehen noch Referenzen auf mich, ich kann mich doch nicht freigeben!":
(testInterface as TTest).Free;// Fehler
Delphi-Quellcode:
if RefCount <> 0 then
Error(reInvalidPtr); |
AW: Classes/Interfaces, Reference counting, wann/wie
Zitat:
Delphi-Quellcode:
Am einfachsten machst du es dir, wenn du den Klassennamen ausschließlich (!) bei der Erstellung der Instanz mit TTest.Create verwendest. Danach solltest du immer mit ITest arbeiten ohne Casts auf TTest oder Variablen vom Typ TTest.
procedure TForm1.Test();
var testInterface: ITest; begin testInterface := TTest.Create; testInterface.CallInterface(testInterface); testInterface := nil; // zur expliziten Freigabe, ohne die Zeile wird es nach dem end darunter freigegeben end; |
AW: Classes/Interfaces, Reference counting, wann/wie
Danke für die Infos. Werde wohl noch etwas testen
|
AW: Classes/Interfaces, Reference counting, wann/wie
Es gibt ein paar Ausnahmen, z.B.
* bei Interfaces ohne Referenzzählung * oder wenn man für den Objektzeiger selbst eine Referenz registriert -> AddRef Ansonsten gibt es eine einfache Regel: NIEMALS Objektreferenzen mit Interfacereferenzen mischen, also entweder mit Objekten arbeite oder mit Interfaces (also sein Objekt gleich zu Beginn ausschließlich in einer Interfacevariable speichern) |
AW: Classes/Interfaces, Reference counting, wann/wie
Zitat:
|
AW: Classes/Interfaces, Reference counting, wann/wie
Nja, aus Sicht des Benutzers sieht er ja nur das Interface, also wird quasi bei diesem "Interface" gezählt oder nicht.
Viele Objekte hinterm Interface haben eine Referenzzählung, aber ja, wenn man es genau nimmt, dann wählt das Objekt und da gibt es auch Welche ohne Mitzählen. |
AW: Classes/Interfaces, Reference counting, wann/wie
@renew auf Coding Bott gibt es übrigens ein Video zum Thema reference counting:
![]() |
AW: Classes/Interfaces, Reference counting, wann/wie
Zitat:
|
AW: Classes/Interfaces, Reference counting, wann/wie
Man kann auch den Constructor mit einer Class Function überdecken (reintroduce) und dort intern mit inherited-Create als Result das Iterface rausgeben.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:02 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