Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TObjectList.Free erzeugt AV (https://www.delphipraxis.net/183819-tobjectlist-free-erzeugt-av.html)

SvB 6. Feb 2015 17:01

Delphi-Version: XE7

TObjectList.Free erzeugt AV
 
Ich stehe gerade etwas auf dem Schlauch und würde mich über eine Tipp freuen.

Ich habe eine TObjectList mit OwnObjects = True. In der Liste sind mehrere Objekte angefügt.
Jetzt hab ich das Problem, dass ein Objekt an anderer Stelle schon frei gegeben wurde und
ObjectList.Free eine Exception auslöst, da das eine Objekt nicht mehr existiert.

Jetzt möchte ich vor dem ObjectList.Free prüfen, ob die Objekte in der Liste noch gültig sind und ungültige aus der Liste entfernen.
Ich hab nur gerade ein Brett vorm Kopf, wie ich das abfrage. Wer kann helfen?

BadenPower 6. Feb 2015 17:42

AW: TObjectList.Free erzeugt AV
 
Wenn Du eine TObjectList hast, bei der die Liste der Eigentümer der Objekte ist, dann solltest Du auch das Freigeben der Objekte der Liste überlassen und die nicht selbst irgendwo freigeben ohne es der Liste mitzuteilen.

Der Schlüssel zum Erfolg liegt bei:

Delphi-Quellcode:
TObjectList.Remove(AObject: TObject);

Sir Rufo 6. Feb 2015 17:47

AW: TObjectList.Free erzeugt AV
 
Das ist doch einfach: Es geht schlicht und ergreifend nicht.

Du hast die Verwaltung der Lifetime der Instanz an die Liste gegeben und nun schmeisst du es irgendwo aus dem Speicher. Das macht man nicht.

Das ist so, als ob du mir etwas schenkst und dann mir wieder wegnimmst. Das gibt auch Mecker (mindestens).

Nur das es bei Referenzen eben schlecht mit dem Kontrollieren aussieht, ob da an der Referenz noch etwas liegt. Denn der Speicher ist noch da (du klaust ja keinen RAM-Riegel aus dem System) und da kann auch noch irgendwas stehen. Es gibt also keine zuverlässige Möglichkeit zu prüfen ob unter der Referenz noch eine gültige Instanz zu finden ist.

Mach es anders und alles wird gut.

SvB 6. Feb 2015 18:05

AW: TObjectList.Free erzeugt AV
 
OK, hatte gehofft, das man das prüfen kann. Dann mach ich anders, ist auch kein Problem.
Danke Euch für die Infos.

jaenicke 6. Feb 2015 18:25

AW: TObjectList.Free erzeugt AV
 
Wenn du anderswo ein entsprechendes eigenes Objekt zum Freigeben benötigst, kannst du ja eine Kopie erstellen. Alles andere wäre nicht sauber.

Eine mögliche Alternative wären Interfaces.

himitsu 6. Feb 2015 19:10

AW: TObjectList.Free erzeugt AV
 
Wenn die Objekte nachfahren von TComponent sind, dann kann man deren Messagesystem benutzen und das Objekt sich selber aus der Liste löschen lassen, wenn es freigegeben wird.
Quasi eine TComponentList mit AutoRemove.

Ab XE wäre das auch für alle anderen Nicht-TComponents relativ leicht möglich und davor bissl schwerer, aber ist nicht wirklich schön, sowas umzusetzen.

SvB 6. Feb 2015 19:56

AW: TObjectList.Free erzeugt AV
 
Ich glaube ich habe mich da etwas verrannt. Nach weiteren Überlegungen passen meine Idee und mein Ansatz dann doch nicht so ganz.

Ich arbeite schon mit einem TInterfacedObject, in dem die TObjectList enthalten ist.
In einem Formular erzeuge ich im OnCreate noch andere benötigte Formulare, deren Referenz ich in der TObjectList ablege, damit die auf jeden Fall aufgeräumt werden, falls es mal krachen sollte.
Die Unterformulare habe ich auf Position = poOwnerFormCenter eingestellt, und wollte die dann schön zentriert über dem Hauptformular anzeigen lassen. Das funktioniert nur, wenn die Unterformulare mit Owner = Hauptformular erzeugt werden.
Wenn ich dann das Hauptformular schließe, dann werden durch den Owner auch die Unterformulare aufgeräumt und danach wird Interfaced ObjectList automatisch aufgeräumt und es gibt die Exception.

Das zentrieren lasse ich jetzt, ich glaube, das war so ein Hirngespinst in das ich mich hineingesteigert habe und nicht wirklich brauche.
Ich glaube, ich werde die Unterformulare auch erst dann erzeugen, wenn ich sie brauche. Sie werden nicht immer alle benötigt und sind nicht sehr umfangreich. Das Erzeugen wird nach Bedarf dann auch schnell gehen.

Sir Rufo 6. Feb 2015 20:03

AW: TObjectList.Free erzeugt AV
 
Warum sagst du denn nicht gleich, dass es sich um Nachfahren von
Delphi-Quellcode:
TComponent
handelt, die du in der Liste speichern möchtest. :wall:

Gerade die senden dir nach Anmeldung eine Nachricht, wenn die sich aus dem Speicher entfernen.
Delphi-Referenz durchsuchenTComponent.FreeNotification
Delphi-Referenz durchsuchenTComponent.RemoveFreeNotification
Fliegt also so eine Instanz weg, ohne dass du die aus der Liste nimmst, dann wirf die einfach aus der Liste raus
Delphi-Quellcode:
CompList.OwnsObjects := False;
try
  CompList.Remove( AComponent );
finally
  CompList.OwnsObjects := True;
end;

BadenPower 6. Feb 2015 20:31

AW: TObjectList.Free erzeugt AV
 
Zitat:

Zitat von Sir Rufo (Beitrag 1289071)
Delphi-Quellcode:
CompList.OwnsObjects := False;
try
  CompList.Remove( AComponent );
finally
  CompList.OwnsObjects := True;
end;

Wenn Du "CompList.Extract( AComponent )" nimmst, dann brauchst Du .OwnObjects nicht zu verändern und auch den "try finally" - Block kannst Du Dir sparen.

Sir Rufo 6. Feb 2015 20:37

AW: TObjectList.Free erzeugt AV
 
Zitat:

Zitat von BadenPower (Beitrag 1289074)
Zitat:

Zitat von Sir Rufo (Beitrag 1289071)
Delphi-Quellcode:
CompList.OwnsObjects := False;
try
  CompList.Remove( AComponent );
finally
  CompList.OwnsObjects := True;
end;

Wenn Du "CompList.Extract( AComponent )" nimmst, dann brauchst Du .OwnObjects nicht zu verändern und auch den "try finally" - Block kannst Du Dir sparen.

Stimmt, kam mir doch gleich so komisch vor :mrgreen:


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:30 Uhr.
Seite 1 von 4  1 23     Letzte »    

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