Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Componenten freigeben... Laufzeitfehler ??! (https://www.delphipraxis.net/12360-componenten-freigeben-laufzeitfehler.html)

Shadow 26. Nov 2003 02:05


Componenten freigeben... Laufzeitfehler ??!
 
Hi @all...

habe da nen kleines Problem und finde den Fehler nicht ....
zunächst zum codeschnipzel...

Delphi-Quellcode:
prozedure tralalala();
var btn : TSpeedButton;
begin
...
for i:=0 to 10 do
begin
btn := TSpeedButton.Create(self);
btn.Parent := vle_Zauber;                   {vl_zauber == TValueList}
vle_Zauber.InsertComponent(btn);
end;
...
end;

Nun will ich alle Komponenten die als Parent vle_Zauber besitzen löschen.....

procedure Tfrm_CharZauber.UnloadCreatedButtons;
var i : Integer;
begin
   begin
      for i:=0 to ComponentCount -1 do
       if (Components[i].ClassType = TSpeedButton) and ((Components[i] as TSpeedButton).Parent = vle_Zauber) then
          begin
            vle_zauber.RemoveComponent(Components[i]);
            (Components[i] as TSpeedButton).Free;
          end;

      end;
end;
Klappt auch ohne Fehler .... nur wenn ich mit dem Programm normal weiter arbeite kommt nach einiger zeit die
Exeption : EAccessViolation at address ...

Sicher ist das ich auf die gelöschten Komponenten zu keiner zeit zugreife. Daran liegt es nicht.

Hat jemand ne Idee ??

MfG Andy

himitsu 26. Nov 2003 08:36

Re: Componenten freigeben... Laufzeitfehler ??!
 
Ein Hallöle von http://www.FrankNStein.de/Smiley-Wolke.gif,

:warn: Erst mal empfehle ich dir die For-Schleife zu ändern:
Code:
[b]For[/b] i := ComponentCount - 1 [color=red][b]downto[/b][/color] 0 [b]do[/b]
Denn wenn etwas gelöscht wird, verschiebt sich doch alles Folgende in der Liste (hier in Components) nach vorn.
Daher kann schon mal etwas übersprungen werden.
Beispiel:
  • wird Komponente 3 gelöscht
  • Komponente 4 rutscht auf Position 3
  • jetzt wird aber mit Position 4 weiter gemacht
  • (das was vorher 4 war, aber jetzt 3 ist wrd übergangen)
Außerdem ist die Liste jetzt ja auch noch kürzer, als beim Einstig in die Schleife, daher ist es dann am Ende der Schleife möglich auf nicht mehr existierende Listeneintäge zuzugreifen, den die Letzten sind ja nach vorne gerutscht.


Jetzt aber zum Fehler, dieser Tritt immer in RemoveComponent auf.
Ich vermute mal, das dort die Komponente nicht so richtig gelöschen/freigegeben wird, Da auch beim beenden des Formulars, selbst wenn in dieser Prozedur mal kein Fehler auftritt, eine nette Fehlermeldung ausgegeben wird.
Da ich aber mit sowas nur sehr selten arbeite, kann ich aber nicht sagen was der Fehler ist. :nerd:
Code:
[b]Procedure[/b] TForm1.Button1Click(Sender: TObject);
  [b]Var[/b] i: Integer;

  [b]Begin[/b]
    [b]For[/b] i := ComponentCount - 1 [b]downto[/b] 0 [b]do[/b]
      [b]If[/b] (Components[i] [b]is[/b] TSpeedButton) [b]and[/b] (TSpeedButton(Components[i]).Parent = vle_Zauber) [b]Then Begin[/b]
        [color=red]vle_zauber.RemoveComponent(Components[i]);[/color]
        TSpeedButton(Components[i]).Free;
      [b]End[/b];
  [b]End[/b];
http://www.delphipraxis.net/images/common/divider.jpg
http://www.FrankNStein.de/Smiley-Kuss.gif * * http://www.FrankNStein.de/Smiley-Spinne.gif * * * http://www.FrankNStein.de/Smiley-Winken.gif

Shadow 26. Nov 2003 13:18

Re: Componenten freigeben... Laufzeitfehler ??!
 
hi...

vielen dank erstmal für den Schleifen Tipp, werde den übernehmen...

>>Ich vermute mal, das dort die Komponente nicht so richtig gelöschen/freigegeben wird, Da auch beim beenden des
>>Formulars, selbst wenn in dieser Prozedur mal kein Fehler auftritt, eine nette Fehlermeldung ausgegeben wird.

??

Delphi-Quellcode:
vle_zauber.RemoveComponent(Components[i]);
Diese Procedure ist ja fest etabliert.. daher sollte doch dort kein Fehler auftreten (hoffe ich zumindetens ;-) )?


mfg Andy

choose 26. Nov 2003 13:55

Re: Componenten freigeben... Laufzeitfehler ??!
 
Die Eigenschaft Components ist eine "Liste" (genauer: Array-Eigenschaft) von Komponenten und sie enthält genau ComponentCount viele Einträge. Wenn Du einen Eintrag entfernst, besitzt sie folglich weniger Einträge, so dass ein Löschen des dritten Eintrags einer Liste mit drei Einträgen zur Folge hat, dass ein Zugriff auf den dritten Eintrag zum Fehler führt: Er existiert nicht länger.
Darüber hinaus ist der Destruktor von TComponent so implementiert, dass sich die Exemplar selbstständig aus der "Liste" Components des durch Owner referenzierten Objekts austragen, so dass Du einfach
Delphi-Quellcode:
with AnObject do
  while ComponentCount>0 do
    Components[0].Free;
schreiben kannst.

Shadow 26. Nov 2003 15:48

Re: Componenten freigeben... Laufzeitfehler ??!
 
habe den code (beziehe mich auf meinen ersten Eintrag) wir folgt geändert....

Delphi-Quellcode:
   for i := ComponentCount - 1 downto 0 do
     if (Components[i].ClassType = TSpeedButton) and ((Components[i] as TSpeedButton).Parent = vle_Zauber) then
          Components[i].Free;

funktioniert ebenfalls... dennoch wird auch hier die oben genannte Exception ausgelöst !?
Hat jemand noch ne Idee wodurch der fehler verursacht wird ? Würde den reservierten Speicher für die
erzeugten Buttons (bis zu 300) gerne freigeben und ungern die Buttons lediglich auf unvisible
schalten :?


mfg Andy

himitsu 26. Nov 2003 18:05

Re: Componenten freigeben... Laufzeitfehler ??!
 
Kannst es aber auch mal anders versuchen. Statt mit Component mal mit FindComponent und so...

Beispiel zum dynamischen erzeugen und löschen von Componenten:
Dynamic-Demo (Komponenten_erzeugen.exe) in meinem 3. oder 4. Post in folgendem Beitrag: Begrenzte Anzahl TEdit-Komponenten??

http://www.delphipraxis.net/images/common/divider.jpg
http://www.FrankNStein.de/Smiley-Kuss.gif * * http://www.FrankNStein.de/Smiley-Spinne.gif * * * http://www.FrankNStein.de/Smiley-Winken.gif


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:07 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