Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Classes/Interfaces, Reference counting, wann/wie (https://www.delphipraxis.net/204730-classes-interfaces-reference-counting-wann-wie.html)

renew 23. Jun 2020 08:22

Classes/Interfaces, Reference counting, wann/wie
 
Hallo,

ich verstehe es nicht ganz, wann das Reference-Counting der Interfaces genutzt wird. Also,

Beispiel:
Code:
  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;
Kann mir jemand erklären, wann das Reference-Counting genutzt wird?

TiGü 23. Jun 2020 08:36

AW: Classes/Interfaces, Reference counting, wann/wie
 
Der Thread hier und der verlinkte Artikel bringen vielleicht etwas Licht ins Dunkel:
https://www.delphipraxis.net/195725-...eferenzen.html

Ggf. für den Einstieg:
http://etutorials.org/Programming/ma...ng+Interfaces/

Der schöne Günther 23. Jun 2020 08:37

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:
(testInterface as TTest).Free;// Fehler
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!":
Delphi-Quellcode:
  if RefCount <> 0 then
    Error(reInvalidPtr);

jaenicke 23. Jun 2020 08:55

AW: Classes/Interfaces, Reference counting, wann/wie
 
Zitat:

Zitat von renew (Beitrag 1468058)
Kann mir jemand erklären, wann das Reference-Counting genutzt wird?

Wenn du nur mit Interfaces arbeitest:
Delphi-Quellcode:
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;
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.

renew 23. Jun 2020 10:06

AW: Classes/Interfaces, Reference counting, wann/wie
 
Danke für die Infos. Werde wohl noch etwas testen

himitsu 23. Jun 2020 12:17

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)

freimatz 23. Jun 2020 14:04

AW: Classes/Interfaces, Reference counting, wann/wie
 
Zitat:

Zitat von himitsu (Beitrag 1468081)
Es gibt ein paar Ausnahmen, z.B.
* bei Interfaces ohne Referenzzählung

Was meinst Du damit? Ein Interface selber hat doch eh keine Referenzzählung sondern das Objekt. Meinst Du Klassen bei denen der Mechanismus ausgehebelt ist?

himitsu 23. Jun 2020 14:33

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.

generic 24. Jul 2020 11:37

AW: Classes/Interfaces, Reference counting, wann/wie
 
@renew auf Coding Bott gibt es übrigens ein Video zum Thema reference counting:
https://www.youtube.com/watch?v=wrnyJW6dtgY

freimatz 24. Jul 2020 19:46

AW: Classes/Interfaces, Reference counting, wann/wie
 
Zitat:

Zitat von jaenicke (Beitrag 1468064)
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.

Oder man verwendet TTest gar nicht. Bei uns werden diese meist in anderen units gehalten wie die interfaces oder im implementation-Teil der unit und die Erzeugung geht über eine Factory-Methode oder gleich über den DI-Container.

himitsu 24. Jul 2020 21:02

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 14:08 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz