Pergunta

Eu tenho uma classe baseada no TinterFacedObject. Eu o adiciono à propriedade de dados da TTreenode.

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

Eu crio muitas instâncias desse objeto e assumi que, como elas são contadas de referência, não preciso libertá -las. Isso seria útil.

No entanto, ao verificar isso, liguei o relatóriomoryleakssonhutdown e descobri que eles não estão sendo libertados, afinal.

Esses objetos estão sendo criados em um quadro colocado na forma principal. No formulário da forma principal, limpo os nós da árvore para que todo objeto seja libertado.

o que está acontecendo?

obrigado pela ajuda!

Foi útil?

Solução

O próprio TinterfacedObject não é contado de referência, apenas as interfaces são. Você pode implementar interfaces usando o TinterFacedObject, que basicamente salva o esforço de implementar os métodos de contagem de referência. Infelizmente, ele ainda não funcionará no seu caso: o compilador não sabe que você está atribuindo interfaces à propriedade ttreenode.data, pois não é declarada como uma interface, mas como um ponteiro. Então, todos os tipos de coisas estranhas vão acontecer:

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

Assim que você tentar acessar seu objeto através da propriedade .Data, você receberá uma violação de acesso.

Portanto, não se preocupe com as interfaces, neste caso, você pode fazê -lo funcionar, mas será muito mais esforço do que vale a pena.

Outras dicas

Você deve declarar o campo/variável como interface

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;

Para acessar seus campos, você deve declarar propriedades na interface ifacilitytreeitem, com getters e setters.

Como Dummzeuch disse, você pode fazer com que isso funcione com interfaces, mas é preciso um pouco mais de código, já que a propriedade de dados de um TTreenode é um ponteiro. Para quem se pergunta como fazer isso, esse link Tem um exemplo de como fazê -lo para o Tlistitem (é praticamente o mesmo para o TTTREENODE). Você também pode achar útil ler a seção sobre interfaces e seção subsequente sobre contagem de referência nessa página.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top