To, co się tutaj dzieje, to wywołanie TContainer.Create
i utworzenie instancji obiektu. Ale potem przypisujesz tę instancję do referencji interfejsu, globalnej zmiennej Foo
. Ponieważ zmienna ta jest typu IFoo
, delegowanie interfejsu oznacza, że obiektem implementującym jest instancja TFooImpl
i nie z instancją TContainer
.
W związku z tym nic nie ma odniesienia do instancji TContainer
, jej licznik referencji nigdy nie jest zwiększany, a więc nigdy nie jest niszczony.
Nie sądzę, aby było to bardzo łatwe. Możesz używać TAggregatedObject
, ale może to nie rozwiązać Twojego problemu. Zmusiłoby to do zadeklarowania, że TContainer.FFoo
ma być typu TFooImpl
, co uważam, że nie chcesz robić. Tak czy inaczej, oto jak to wygląda przeredagowanej ten sposób:
program SO16210993_TAggregatedObject;
{$APPTYPE CONSOLE}
type
IFoo = interface
procedure Foo;
end;
TFooImpl = class(TAggregatedObject, IFoo)
procedure Foo;
end;
TContainer = class(TInterfacedObject, IFoo)
private
FFoo: TFooImpl;
function GetFoo: IFoo;
public
destructor Destroy; override;
property Foo: IFoo read GetFoo implements IFoo;
end;
procedure TFooImpl.Foo;
begin
Writeln('TFooImpl.Foo called');
end;
destructor TContainer.Destroy;
begin
Writeln('TContainer.Destroy called');//this line does run
FFoo.Free;
inherited;
end;
function TContainer.GetFoo: IFoo;
begin
if not Assigned(FFoo) then
FFoo := TFooImpl.Create(Self);
Result := FFoo;
end;
procedure Main;
var
Foo : IFoo;
begin
Foo := TContainer.Create;
Foo.Foo;
end;
begin
Main;
Readln;
end.
documentation nie mówi na ten temat:
Klasa użyć, aby implementować interfejs delegowane powinny pochodzić z TAggregationObject.
Początkowo nie mogłem znaleźć żadnej dokumentacji dla tego TAggregationObject
. I wreszcie zdałem sobie sprawę, że faktycznie ma on nazwę TAggregatedObject
i jest to documented.
TAggregatedObject zapewnia funkcjonalność dla wewnętrznej przedmiotu w agregatu poprzez wdrożenie metod IInterface powierzyć sterującego IInterface The.
Zagregowany obiekt to obiekt złożony z kilku połączonych obiektów . Każdy obiekt implementuje własne zachowanie i interfejsy, ale wszystkie obiekty mają tę samą liczbę odniesienia, która jest obiektem obiektu kontrolera . W układzie pojemnika kontrolerem jest obiekt kontenerowy .
Obiekt TAggregatedObject sam nie obsługuje żadnych interfejsów. Jednakże, jako typowe dla agregatu, implementuje on metody IInterface, które są używane przez obiekty, które z niego się wywodzą. Obiekt TAggregatedObject służy jako baza dla klas, które implementują interfejsy do tworzenia obiektów, które są częścią agregatu .
Obiekt TAggregatedObject służy jako baza dla klas tworzących obiekty i łączących obiekty.Korzystanie z obiektu TAggregatedObject zapewnia, że wywołania do metod interfejsu IInterfejsu delegują do kontrolera IInterface agregatu.
Kontrolny interfejs II jest określony w konstruktorze dla TAggregatedObject i jest wskazywany przez właściwość Controller.
Ponadto jest to z uwagi kodu źródłowego:
TAggregatedObject i TContainedObject są odpowiednie klasy bazowe interfejsowych do obiektów, które mają być łączone lub zawarte w zewnętrznej obiektu sterującego. Używając składni "narzędzi" dla właściwości interfejsu obiektu w deklaracji zewnętrznej klasy obiektu, należy użyć tych typów do implementacji obiektu wewnętrznego.
Interfejsy implementowane przez zagregowane obiekty w imieniu kontrolera nie powinny być odróżnialne od innych interfejsów dostarczonych przez kontroler. Zagregowane obiekty nie mogą przechowywać własnej liczby referencyjnej - muszą mieć ten sam czas życia co ich kontroler. Aby to osiągnąć, zagregowane obiekty odzwierciedlają metody liczników odwołań do kontrolera.
Obiekt TAggregatedObject po prostu odzwierciedla wywołania QueryInterface do kontrolera . Z takiego zagregowanego obiektu można uzyskać dowolny interfejs obsługiwany przez kontroler i tylko interfejsy obsługiwane przez kontroler . Jest to przydatne do implementacji klasy kontrolera , która używa jednego lub więcej wewnętrznych obiektów do implementacji interfejsów zadeklarowanych w klasie kontrolera. Aggregation promuje współużytkowanie implementacji w hierarchii obiektów.
Obiekt TAggregatedObject jest dziedziną, w której większość obiektów zbiorczych powinna odziedziczyć , szczególnie jeśli jest używana w połączeniu ze składnią "toolss" .
"Czy coś pomijam?" Nie wiem Ale na pewno jesteśmy. Zapomniałeś podać kod! Wymagany jest pełny program demonstrujący zachowanie. W przeciwnym razie musimy zgadywać. –
masz dodatkowe referencje lub pętle referencyjne. Dodaj przesłonięcia dla TFirstSecond._AddRef i TFirstSecond._Release i umieść tam punkty przerwania, uzyskaj pełną listę odnośników i zobacz, które z nich nie zostały wyczyszczone. –
Problem polega na tym, że twoje interfejsy są delegowane. Nie wiem, dlaczego to powoduje to zachowanie. –