집계를 사용하여 여러 자식 객체가 포함 된 클래스 TParent
을 작성하고 싶습니다. 일부 개체는 독립적이며 일부 개체는 다른 자식 개체에도 종속 될 수 있습니다. 모든 자식 객체는 부모에 대한 참조를 가져야합니다. 가능한 경우 인터페이스를 사용하고 싶습니다.Delphi : [weak] 속성을 사용한 객체 집계 및 메모리 누출
아동용 TParent
및 TAggregatedObject
은 TInterfacedObject
입니다. 아이와 부모 모두 서로에 대해 알고 있기 때문에 나는 약한 의존성을 피하기 위해 약한 참조를 사용하고 있습니다. 사실이 동작은 이미 TAggregatedObject
에 정의되어 있습니다. 독립적 인 자식 객체 (TIndependantChild
) 만 사용하면 모든 것이 잘 작동합니다.
자식 개체가 다른 자식에도 종속 될 때 문제가 발생합니다. 생성자 TDependantChild
을 참조하십시오. 델파이 10 베를린에 도입 된 [weak]
attibute로 표시된 fChild 변수에 다른 자식 객체에 대한 참조를 저장합니다.
는 또한 System.TMonitor.Destroy
인상으로 이어지는 위반에 액세스하지만 FastMM4가이 용도에 있으며 ReportMemoryLeaksOnShutDown이 True 인 경우에만이 문제가 발생합니다 : FastMM4가가 종료시 메모리 누수를보고합니다.
program Project1;
{$APPTYPE CONSOLE}
uses
FastMM4,
System.SysUtils;
type
IParent = interface
['{B11AF925-C62A-4998-855B-268937EF30FB}']
end;
IChild = interface
['{15C19A4E-3FF2-4639-8957-F28F0F44F8B4}']
end;
TIndependantChild = class(TAggregatedObject, IChild)
end;
TDependantChild = class(TAggregatedObject, IChild)
private
[weak] fChild: IChild;
public
constructor Create(const Controller: IInterface; const AChild: IChild); reintroduce;
end;
TParent = class(TInterfacedObject, IParent)
private
fIndependantChild: TIndependantChild;
fDependantChild: TDependantChild;
public
constructor Create;
destructor Destroy; override;
end;
{ TParent }
constructor TParent.Create;
begin
fIndependantChild := TIndependantChild.Create(Self);
fDependantChild := TDependantChild.Create(Self, fIndependantChild);
end;
destructor TParent.Destroy;
begin
fDependantChild.Free;
fIndependantChild.Free;
inherited;
end;
{ TDependantChild }
constructor TDependantChild.Create(const Controller: IInterface; const AChild: IChild);
begin
inherited Create(Controller);
fChild := AChild;
end;
var
Owner: IParent;
begin
ReportMemoryLeaksOnShutDown := True;
Owner := TParent.Create;
Owner := nil;
end.
가 나는 것을 발견하여 [안전] 약한 상기 문제를 해결하지만,
그것은 ([안전])에만 시스템 유닛 외부 표기 help 델파이 따른 대신 매우 드물게 발생합니다.
따라서 여기에 [unsafe]
을 사용해야한다고 확신하지 못합니다. 특히 어떤 일이 발생하는지 이해하지 못하는 경우에는 특히 그렇습니다.
그래서이 상황에서 메모리 누수가 무엇이며이를 극복하는 방법은 무엇입니까?
왜 아이들을 집계해야합니까? 집계가 실제로 무엇인지 이해합니까? 왜 객체 참조와 인터페이스를 혼합하고 있습니까? 그것은 항상 재앙을위한 처방입니다. 디버거를 사용하여 메모리 누수 원인을 확인하십시오. –
10.1 Berlin의 인터페이스에는'[weak]'이 추가되었지만 이전 버전에서는'[weak]'이 존재합니다. XE2에서 코드를 그대로 컴파일 할 수는 있지만'[weak]'은 효과가 없습니다. 왜냐하면'TDependantChild'는'[weak] '임에도 불구하고'fChild'가 할당되었을 때 (집합 때문에)'TParent'에 대한 비 weak 참조를 가지고 있기 때문에'Owner'는'RefCount = 1'을가집니다. 'Owner'가 파기되면,'TInterfacedObject.BeforeDestruction()'은'RefCount <> 0' 에러를 일으켜'Owner '와 그 자식을 유출시킵니다. 'fChild'를'Pointer'로 바꾸면 그것을 수정합니다. 나는 당신의 경우에''안전하지 않은 ''을 사용할 때 비슷한 것으로 의심합니다. 디버거로 확인 –
레미, 코멘트 주셔서 감사합니다. 나는 집합 개념을 처음 접했을 뿐이다. 틀림없이 그것을 이해했다. 필자의 경우 자식 객체는 특정 클래스 기능을 나타냅니다. 그들은 부모 없이는 아무 감정도 갖지 않지만 동일한 아이 개체는 다른 부모를 구성하는 데 사용될 수 있습니다. 인터페이스와 객체 참조도 섞어 놓는 것을 좋아하지는 않았지만 여러 가지 예제를 발견했습니다. [link] (https://stackoverflow.com/questions/3483680/delphi-how-delegate-interface-implementation-to-child -object), 인터페이스 만 사용하면 오류가 발생합니다. 나는 곧 두 번째위원회를 점검 할 것이다. – VyPu