문제

TinterfacedObject를 기반으로 한 수업이 있습니다. TTREENODE의 데이터 속성에 추가합니다.

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

나는이 객체의 많은 인스턴스를 만들고 그들이 참조가 계산 되었기 때문에 그것을 자유롭게 할 필요는 없다고 가정했다. 그것은 편리 할 것입니다.

그러나 이것을 확인할 때, 나는 reportmemoryLeakSonShutdown을 켜고 결국 그들이 해방되지 않았다는 것을 알았습니다.

이 객체는 기본 형태에 놓인 프레임으로 만들어지고 있습니다. 기본 형태의 Formclose에서는 모든 객체가 풀리도록 트리 노드를 지 웁니다.

무슨 일이야?

도와 주셔서 감사합니다!

도움이 되었습니까?

해결책

TinterfacedObject 자체는 참조 계산이 아니며 인터페이스 만 있습니다. 기본적으로 참조 계산 방법을 직접 구현하려는 노력을 절약 할 수있는 TinterfacedObject를 사용하여 인터페이스를 구현할 수 있습니다. 불행히도 여전히 귀하의 경우에도 여전히 작동하지 않습니다. 컴파일러는 인터페이스가 아니라 포인터로 선언되기 때문에 TtreEnode.data 속성에 인터페이스를 할당하고 있음을 알지 못합니다. 그래서 모든 종류의 이상한 일이 일어날 것입니다.

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

.Data 속성을 통해 객체에 액세스하려고하자마자 액세스 위반을 받게됩니다.

따라서이 경우 인터페이스를 귀찮게하지 말고 작동하게 할 수 있지만 가치보다 훨씬 더 많은 노력이 될 것입니다.

다른 팁

필드/변수를 인터페이스로 선언해야합니다

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;

필드에 액세스하려면 getters and setters와 함께 ifacilityTreeItem 인터페이스의 속성을 선언해야합니다.

처럼 Dummzeuch가 말했다, 당신은 이것을 인터페이스와 함께 작동시킬 수 있지만, ttreeNode의 데이터 속성이 포인터이기 때문에 더 많은 코드가 필요합니다. 어떻게하는지 궁금해하는 사람이라면 누구나 이 링크 tlistitem을 위해 그것을하는 방법의 예가 있습니다 (ttreenode와 거의 동일합니다). 또한 섹션을 읽는 것이 유용 할 수도 있습니다. 인터페이스 해당 페이지의 참조 계산에 대한 후속 섹션.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top