TObject->
TPersistent->
TComponent->
TFmxObject->
TControl
Darum gelten für ein
TControl
die Regeln für
TComponent
und
TFmxObject
Weil unter ARC die Uhren anders ticken braucht man eine andere Strategie was den Destructor angeht.
Der Destructor wird unter ARC automatisch aufgerufen, wenn der RefCount auf 0 geht (keiner will mehr mit der Instanz spielen).
Würde jetzt mit
Free
unter ARC auch der Destructor aufgerufen, dann würde dieser mindestens
zweimal aufgerufen:
Delphi-Quellcode:
var
foo: TFoo;
foo.Free; // Destructor wird aufgerufen (ohne ARC)
foo := nil; // Destructor wird aufgerufen (mit ARC)
Ist das auch jedem bewusst? Denn das wäre ein anderes Verhalten als man es gewohnt ist.
Darum gibt es die
DisposeOf
Methode, weil ich als Programmierer damit (hoffentlich)
ganz bewusst den Doppelaufruf des Destructors akzeptiere.
Delphi-Quellcode:
var
foo: TFoo;
foo.DisposeOf; // Destructor wird aufgerufen (immer)
foo := nil; // Destructor wird aufgerufen (ARC)
Im Destructor kann man noch den Status
TObject.Disposed abfragen um eine Aktion auch garantiert nur einmal auszuführen.
Delphi-Quellcode:
destructor TFoo.Destroy;
begin
CloseHandle( FHandle );
inherited;
end;
Wer sieht das Problem?
Unter ARC könnte ich damit ein
Handle schliessen, was ich aber gar nicht schliessen möchte.
Der Destructor sollte so aussehen
Delphi-Quellcode:
destructor TFoo.Destroy;
begin
if not Disposed then
begin
CloseHandle( FHandle );
end;
inherited;
end;
denn nur so wird das Freigeben des
Handle auch nur einmal ausgeführt.
PS Die Beispiele in der Dokumentation von Emba beinhalten einen Fehler, denn die Eigenschaft
TObject.Disposed ist
protected
und kann von aussen gar nicht abgefragt werden