Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Verständnisfrage zu ARC (https://www.delphipraxis.net/177344-verstaendnisfrage-zu-arc.html)

Union 1. Nov 2013 12:58

Delphi-Version: XE2

Verständnisfrage zu ARC
 
Hinweis: Es handelt sich um XE5, läßt sich hier aber nicht auswählen.

Ich habe eine zur Laufzeit erzeugte Firemonkey-Komponente. Die will ich von Zeit zu Zeit neu erzeugen. Bisher war ich es ja gewohnt, das mit Free oder FreeAndNil zu machen. Leider verschwindet die Komponente aber nicht. Erst mit DisposeOf.

Das ist natürlich gefährlich, da man ja jahrelang so gearbeitet hat. Manchmal funktioniert es, manchmal nicht. Was muß man da für ein Pattern verwenden? Welche Schritte sind wann zu beachten.

Delphi-Quellcode:
interface
...
TfrmDisplay = class(TForm)
...
public
  Target : TTarget;
  Painter : TTargetPainter;
  CursorCircle : TEllipse;
end;
...
implementation
...
procedure TfrmDisplay.Init;
begin
  if Assigned(Target) then Target.Free;
  if Assigned(Painter) then Painter.Free;
  // Mit Free oder FreeAndNil bleibt die Komponente stehen und bei jedem
  // Aufruf der Init-Procedur kommt eine hinzu.
  if Assigned(CursorCircle) then CursorCircle.DisposeOf;
  ...                                            
  CursorCircle := TEllipse.Create(ImageControl1);
  ...
end;

Daniel 1. Nov 2013 13:21

AW: Verständnisfrage zu ARC
 
Gehört die FMX-Komponente irgendwem? Wenn ja, dann müsstest Du dessen .RemoveObject()-Methode aufrufen. Danach kannst Du es dann freigeben.

Union 1. Nov 2013 13:39

AW: Verständnisfrage zu ARC
 
Ja, die gehört jemand. In dem Beispiel ein Imagecontrol. Nein, das muß ich nicht. Es verhält sich plattformabhängig! Bei einer Windows-Firemonkey-Anwendung verschwindet die Komponente durch das Free. Bei iOS z.b. nicht. Ich habe bei beiden das gleiche Framework, nämlich Firemonkey. "Nur" der Compiler ist unterschiedlich. Ich will eben so was vermeiden:
Delphi-Quellcode:
{$IFDEF NEXTGEN}
{$IFDEF ANDROID}
Mist.DisposeOf
{$ELSE}
FreeAndNil(Mist)
{$ENDIF}
{$ELSE}
Mist.Free;
{$ELSE}

Daniel 1. Nov 2013 13:50

AW: Verständnisfrage zu ARC
 
Aber sicher verhält es sich plattform-abhängig. Der Compiler für Win32 / Win64 hat doch gar kein ARC.

Der NEXTGEN-Compiler ersetzt einen Aufruf von .Free durch eine Zuweisung auf NIL. Ein .Free kannst Du damit für alle Compiler gleichermaßen verwenden, das IFDEF ist nicht erforderlich.

Mit .DisposeOf() führst Du den Code aus, der im Destruktor des Objektes enthalten ist. Eine Freigabe erfolgt (allein) dadurch nicht.

Union 1. Nov 2013 13:55

AW: Verständnisfrage zu ARC
 
Mir geht es um die Plattform-Unabhängigkeit. Die ist also erst dann gegeben, wenn ich Libaries, die jahrelang immer funktionierten, mit defines komplett überarbeiten muß? Weil u.U. das Free gar nix mehr tut...

Daniel 1. Nov 2013 13:58

AW: Verständnisfrage zu ARC
 
Das .Free löst eine Referenz auf ein Objekt auf und bewirkt, dass dessen Referenz-Zähler um eines nach unten geht. Ist dieser bei Null angekommen, so wird das Objekt unmittelbar an dieser Stelle freigegeben.
Und ja, es gibt bestimmt einige Bibliotheken, die unter Win32 anständig funktionieren, aber nicht ARC-fähig sind.

Union 1. Nov 2013 14:01

AW: Verständnisfrage zu ARC
 
Durch das Zuweisen von Parent UND dem Setzen von Owner im Constructor wird also vermutlich der Referenzähler zweimal erhöht?

Daniel 1. Nov 2013 14:36

AW: Verständnisfrage zu ARC
 
Ja, allein ein Label auf einem Form hat 5 Referenzen. Parent, Owner, ein Styler, vielleicht ein Gesture-Manager - es kann viele Gründe dafür geben. Das ist nicht per se schlimm, so lange das Framework weiß, wann es was aufzuräumen hat. Deswegen ja mein Hinweis auf ".RemoveObject()". Dort werden genau diese Referenzen wieder aufgedröselt.

BUG 2. Nov 2013 01:38

AW: Verständnisfrage zu ARC
 
Zitat:

Zitat von Union (Beitrag 1234168)
Ich will eben so was vermeiden

Im Zweifelsfall kannst du es ja in einer Prozedur verstecken :mrgreen:

Habe ich es richtig verstanden, dass
Delphi-Quellcode:
Mist.removeObject();
FreeAndNil(Mist);
immer (gleich) funktionieren sollte, wenn nicht noch irgendwo andere Referenzen rumliegen, die man selbst zu verantworten zu hat :gruebel:

Das die Umstellung bzw. das Nebeneinander von manueller Speicherverwaltung und ARC nicht ohne Reibungsverluste funktioniert, ist irgendwie nicht wirklich überraschend.

Union 2. Nov 2013 08:57

AW: Verständnisfrage zu ARC
 
Da werde ich wohl mal einige Versuche mit refcount machen. Ansonsten gilt wohl als Best Practice: Sämtliche Free durch DisposeOf ersetzen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:19 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz