Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#12

AW: Problem mit ARC unter iOS?

  Alt 22. Jan 2016, 03:03
Delphi-Referenz durchsuchenTObject->Delphi-Referenz durchsuchenTPersistent->Delphi-Referenz durchsuchenTComponent->Delphi-Referenz durchsuchenTFmxObject->Delphi-Referenz durchsuchenTControl
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 Delphi-Referenz durchsuchenTObject.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 Delphi-Referenz durchsuchenTObject.Disposed ist protected und kann von aussen gar nicht abgefragt werden
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (22. Jan 2016 um 03:16 Uhr)
  Mit Zitat antworten Zitat