Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Dynamisches Array of TButton löschen (SetLength)!? (https://www.delphipraxis.net/181232-dynamisches-array-tbutton-loeschen-setlength.html)

weisswe 28. Jul 2014 11:18

Dynamisches Array of TButton löschen (SetLength)!?
 
Hallo!

Irgendwie hab ich eine Denkfehler und weis nicht was ich vergessen habe.
Habe ein dynamisches Array (Array of TButton) welches ich löschen möchte.
Hat bis dato unter FMX/Windows gut funktioniert. Aber wenn ich jetzt eine iOS App mache bekomme ich einen Absturz / Programmabbruch / Zugriffsverletzung.
Problem/Denkfehler mit ARC?

Hier der Code:
Code:
const imax = 3;
var bb: Array of TButton;
    i: Integer;
begin
   // Array füllen
   SetLength(bb, imax);
   for i := 0 to imax - 1 do
   begin
      bb[i] := TButton.Create(Self);
      bb[i].Name := 'Btn' + IntToStr(i+1);
      bb[i].Text := bb[i].Name;
      bb[i].Parent := xcomponent;
   end;
   // Komponenten (Buttons) löschen
   for i := imax - 1 downto 0 do
      bb[i].Destroy;
   // Array leeren
   SetLength(bb, 0); // <-- FEHLER!!!???
end;
Grüße und Danke,
Werner

Stevie 28. Jul 2014 11:42

AW: Dynamisches Array of TButton löschen (SetLength)!?
 
Erstmal nur nebenbei: man sollte nicht Destroy direkt aufrufen sondern Free

Dann zu dem Problem allgemein: unter iOS und Android benutzt der Compiler ARC.
Hättest du dort Free aufgerufen, würde unter NEXTGEN compilern zu einer Zuweisung auf nil kompiliert.

Normalerweise werden Objekte unter ARC über ihren RefCount gehandelt (so wie Interfaces). Allerdings beißt sich das ein bisschen mit dem TComponent Management über den Owner.
Deshalb muss man hier DisposeOf (das geht dann auch für nicht NEXTGEN, somit keine ifdefs notwendig) aufgerufen werden, was zwar den Destructor aufruft aber nicht den internen RefCount verändert.
Wenn du nämlich das Array leerst, wird dort auch entsprechender Code ausgeführt, der den RefCount der Instanzen herunter setzt.

Generell sollte man aber beachten, dass man das Verwalten von TComponent Objekten entweder selbst verwaltet oder über den Owner regeln lässt. Beim selbst verwalten, sollte man dann auch nil an den Konstruktor übergeben damit sich das nicht vermischt.

Ich kann es gerade nicht ausprobieren, aber wenn du nil übergibst, dann kannst du dir glaube ich auf Mobile die Schleife sparen, die die Instanzen freigibt und einfach das Array leeren, denn die Instanzen werden dann implizit über den auf 0 sinkenden RefCount freigegeben.

weisswe 28. Jul 2014 12:12

AW: Dynamisches Array of TButton löschen (SetLength)!?
 
Vielen Dank Stefan!!!
Hat mir sehr geholfen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:12 Uhr.

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