tinterfacedobject

___ answer781175 ___

Leider erzeugt der Delphi-Compiler nur dann den notwendigen Code, um die Anzahl der inc / dec-Referenzen zu ermitteln, wenn Sie Schnittstellen verwenden (in Ihrem Fall die benutzerdefinierte Schnittstelle IFileInfo). Wenn Schnittstellen in den Zeiger (oder auch in TObject) umgewandelt werden, ist außerdem keine Referenzzählung möglich. Zum Beispiel, Assumming globale Variablenliste: TList:

%Vor%

nachdem die Methode returns list [list.Count - 1] einen blinkenden Zeiger enthält.

So können Interfaces nicht in einer Hashmap verwendet werden, die sie in Pointer umwandelt, die Implementierung von hashmap muss sie als IInterface erhalten.

    
___ qstntxt ___

In meinem Code verwende ich eine kleine Datenspeicherklasse, die an verschiedenen Stellen erstellt wird. Um Speicherlecks zu vermeiden und Dinge zu vereinfachen, möchte ich die Referenzzählung verwenden, also tat ich

%Vor%

und entfernte alle meine manuellen Aufrufe zu TFileInfo.Free. Leider hat Delphi viele Speicherlecks gemeldet. Bei der Suche nach SO habe ich die folgende Frage gefunden, die erklärt, warum das nicht funktioniert:

Warum werden keine Nachkommen von TInterfacedObject-Garbage gesammelt?

Es gibt einen Workaround, der dort vorgestellt wird, aber es erfordert von mir (zumindest wenn ich es richtig verstehe), ein benutzerdefiniertes Interface IFileInfo zu schreiben und es mit einer Menge Getter und Setter zu versehen, die ich vermeiden möchte.

BEARBEITEN Ich sollte hinzufügen, dass ich die create FileInfo-Objekte in zwei verschiedene Arten von Hash-Tabellen einfüge: eine von TBucketList und eine Hash-Map-Implementierung aus dem Codegear-Forum. Intern sind sie beide Zeiger, so ist die Situation wie in der anderen Frage.

Gibt es eine andere Möglichkeit, Objekte in Delphi Referenzzählung zu verwenden?

    
___ answer782657 ___

Die Referenzzählung in Delphi funktioniert nur, wenn Sie nur über eine Schnittstelle auf Ihre Instanz verweisen. Sobald Sie Schnittstellenreferenzen und Klassenreferenzen mischen, sind Sie in Schwierigkeiten.

Im Wesentlichen möchten Sie eine Referenzzählung durchführen, ohne dass Sie eine Schnittstelle mit allen darin definierten Methoden und Eigenschaften erstellen müssen. Es gibt drei Möglichkeiten, dies zu tun, und diese sind ungefähr in der Reihenfolge, die ich ihnen empfehlen würde.

  1. Barry Kelly hat einen Beitrag über Smart Pointers geschrieben. Es verwendet die Generics in Delphi 2009, aber ich bin mir ziemlich sicher, dass Sie es hart auf die spezifischen Versionen des Typs codieren könnten, die Sie verwenden, wenn Sie 2009 noch nicht verwenden (es ist eine großartige Veröffentlichung BTW).

  2. Eine weitere Möglichkeit, die mit mehr Versionen von Delphi und weniger Modifikationen funktioniert, ist der Werttyp-Wrapper von Janez Atmapuri Makovsek. Es ist ein Beispiel für TStringList implementiert, aber Sie könnten es für jeden Typ anpassen.

  3. Der dritte Weg besteht darin, einen Schnittstellenzeiger zu erstellen (ähnlich dem Smart Pointer von Barry, aber nicht so intelligent). Ich glaube, es gibt einen in JCL, aber ich erinnere mich nicht an die Details. Im Grunde ist dies eine Schnittstelle, die eine TObject-Referenz bei der Konstruktion akzeptiert. Wenn der Referenzzähler null erreicht, ruft er das Objekt, das Sie ihm übergeben haben, kostenlos auf. Diese Methode funktioniert nur für kurzlebige Instanzen, die Sie nicht als Parameter übergeben, da Sie die Referenzzählung von der tatsächlich verwendeten Referenz trennen. Ich würde stattdessen eine der beiden anderen Methoden empfehlen, aber wenn Sie diese Methode bevorzugen und weitere Informationen wünschen, lassen Sie es mich wissen.

Das ist die Sache mit Delphi, es gibt freie Wege, Dinge zu erreichen. Option # 1 ist die beste meiner Meinung nach - Holen Sie Delphi 2009 und verwenden Sie diese Methode, wenn Sie können.

Viel Glück!

    
___ answer782049 ___

Mischen Sie keine Objektverweise und Schnittstellenreferenzen.

%Vor%     
___ answer782994 ___

Wenn Sie Aufrufe von TObject-Instanzen für die Freigabe deaktivieren möchten, sollten Sie sich einen Speicherbereiniger für natives Delphi ansehen. Ich kenne 2 verschiedene Müllsammler und eine Müllsammeltechnik mit Vor- und Nachteilen.

Einer von denen wird wahrscheinlich für Sie arbeiten.

    
___ tag123delphi ___ Delphi ist eine Sprache für die schnelle Entwicklung von nativen Windows-, macOS-, Linux-, iOS- und Android-Anwendungen mithilfe von Object Pascal. Der Name bezieht sich sowohl auf die Delphi-Sprache als auch auf deren Bibliotheken, Compiler und IDE, mit denen Delphi-Projekte bearbeitet und debuggt werden können. ___ answer781162 ___

Diese Funktionalität wird für Schnittstellen bereitgestellt, nicht jedoch für Objekte.

Sie können so etwas erstellen, aber Sie müssen einige der Struktur von TObject überschreiben:

%Vor%

Sie müssen RefCountedCopy verwenden, um das Objekt einer anderen Variablen zuzuordnen. Aber dann haben Sie ein refcounted Objekt.

Wie man das benutzt:

%Vor%     
___ answer782715 ___

Um zu dem bereits Gesagten hinzuzufügen, verwenden Sie eine TInterfaceList , wenn Sie Verweise auf Schnittstellen speichern möchten, anstatt eine TList zu verwenden. Die ref count wird konsistent arbeiten.

    
___ answer781241 ___

Es gibt eine lange Erklärung dafür, aber kurz gesagt: Wenn Sie TInterfacedObject vererben (und Free selbst nicht aufrufen), reicht das nicht aus, Sie müssen ein Objekt-Factory-Dynamic verwenden, um die Objekte für Sie zu erstellen, Zeiger auf das Objekt überall, nicht nur Objekt-Referenz-Variablen. (Ja, das bedeutet, Sie können nicht einfach "alten Code" wechseln, ohne es zu überdenken)

    
___ tag123interface ___ Eine Schnittstelle bezieht sich auf den Interaktionspunkt zwischen Komponenten. Schnittstellen sind sowohl auf der Hardware- als auch auf der Softwareebene anwendbar. Im Allgemeinen stellt eine Schnittstelle einen Vertrag offen, ohne die zugrunde liegenden Implementierungsdetails offenzulegen. In objektorientierter Programmierung definieren Schnittstellen abstrakte Typen, die das Verhalten offen legen, aber keine Logik enthalten. Die Implementierung wird durch die Klasse oder den Typ definiert, der die Schnittstelle implementiert. ___ qstnhdr ___ Referenzzählung für Objekte ___ tag123referencecounting ___ Das Referenzzählen ist ein Mechanismus, bei dem eine Computersprache beim Erstellen eines Objekts verfolgt und dann kein Objekt oder eine Datenstruktur mehr benötigt, um nicht benötigten Speicher freizugeben. Traditionell wurde dies vom Programmierer manuell vorgenommen. ___ tag123interfacedobject ___ TInterfacedObject ist eine Basis für einfache Klassen, die das grundlegende IInterface implementieren. Es ist in der System.pas-Einheit definiert. ___
7
Antworten

Referenzzählung für Objekte

In meinem Code verwende ich eine kleine Datenspeicherklasse, die an verschiedenen Stellen erstellt wird. Um Speicherlecks zu vermeiden und Dinge zu vereinfachen, möchte ich die Referenzzählung verwenden, also tat ich %Vor% und entfernte alle...
23.04.2009, 10:10