Frage

Ich habe eine Klasse basierend auf TInterfacedObject. i fügen Sie es TTreeNode Data-Eigenschaft.

TFacilityTreeItem=class(TInterfacedObject)
private
  m_guidItem:TGUID;
  m_SomeOtherNode:TTreeNode;
public
end;

i schaffen viele Instanzen dieses Objekt & hatte angenommen, dass, weil sie Bezug gezählt sind, sollte ich nicht, sie befreien müssen. das wäre praktisch.

Wenn jedoch diese Überprüfung, schaltete ich ReportMemoryLeaksOnShutdown und fand sie nicht schließlich befreit werden.

Diese Objekte werden in einem Rahmen geschaffen, der auf der Hauptform gesetzt wird. in der Formclose Haupt Form, mir klar die Baumknoten, so dass jedes Objekt befreit werden soll.

Was ist los?

Danke für Ihre Hilfe!

War es hilfreich?

Lösung

TInterfacedObject selbst über keine Referenz gezählt wird, sind nur Schnittstellen. Sie können Schnittstellen implementieren TInterfacedObject verwendet, die sich die Mühe erspart Ihnen im Grunde von selbst die Referenz Zählverfahren zu implementieren. Leider wird es immer noch nicht in Ihrem Fall: Der Compiler weiß nicht, dass Sie Schnittstellen zur TTreeNode.Data Eigenschaft zuweisen, da es nicht als eine Schnittstelle, sondern als Zeiger deklariert wird. Also alle Arten von seltsamen Dingen passieren:

MyInt := TFacilityTreeItem.Create; // ref count = 1
// Node.Data := MyInt; // won't compile
Node.Data := pointer(MyInt); // no interface assignment, ref count stays 1
...
end; // ref count reaches 0, your object gets freed

Sobald Sie Ihr Objekt durch die .Data Eigenschaft zuzugreifen versuchen, erhalten Sie eine Zugriffsverletzung erhalten.

So

, nicht die Mühe mit Schnittstellen in diesem Fall könnten Sie es an der Arbeit, aber es wird viel mehr Mühe, als es wert ist.

Andere Tipps

Sie sollten das Feld / Variable als Schnittstelle deklarieren

IFacilityTreeItem = IInterface
end;

TFacilityTreeItem=class(TInterfacedObject, IFacilityTreeItem)
private
  m_guidItem:TGUID;
  m_SomeOtherNode:TTreeNode;
end;

var
  Item: IFacilityTreeItem; // Variable as Interface
begin
  Item:= TFacilityTreeItem.Create;
...
end;

Ihre Felder zugreifen zu können, sollten Sie Eigenschaften in IFacilityTreeItem Schnittstelle deklarieren, mit Getter und Setter.

Wie dummzeuch sagte , können Sie sich dies mit Schnittstellen zu arbeiten, aber es dauert einige mehr Code, da die Data-Eigenschaft eines TTreeNode ein Zeiger ist. Für alle, fragen, wie das zu tun, Link hat ein Beispiel wie es für TListItem tun (es so ziemlich das gleiche für TTreeNode ist). Sie können auch es nützlich finden Sie im Abschnitt über Schnittstellen und anschließenden zu lesen Abschnitt über Referenzzählung auf dieser Seite.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top