Hi und herzlich Willkommen in der
DP
Zu dem Thema create/destroy gibt es gleich ein paar Dinge zu sagen. Am schönsten ist es natürlich, wenn du hier den Leuten hilfst, die dir helfen sollen und genauer sagst, was dir schon bekannt ist und was eben noch nicht. In diesem Fall wären Begriffe wie Konstruktor/Destruktor dass, wonach du schauen solltest.
Bei create handelt es sich um den Constructor, dieser wird benötigt um eine neue Instanz einer Klasse zu erzeugen. Die Klasse TObject besitzt einen speziellen Konstruktor, also sein Implmentierung ist speziell, denn hier wird tatsächlich ein neues Objekt erstellt, der Speicher reserviert usw. Jede andere Klasse ist immer ein Nachfahre von TObject und erbt deswegen diesen Konstruktor. Schreibst du einen eigenen ist deswegen der wichtigste Aufruf (der in deiner eigenen Implementierung als erstes erfolgen muss) inherited create (du rufst damit den geerbten Konstruktor auf, was irgendwann zum Aufruf des TObject.Create führt).
Rufst du einen Konstruktor auf, so wird eine Referenz auf das erzeugte Objekt zurückgegeben. Eine solche Referenz ist etwas wie ein Zeiger auf ein Objekt. Der Aufruf des Destruktors kann auf zwei Arten erfolgen, du kannst direkt den Destruktor aufrufen (Destroy) oder du verwendest die Methode Free. Diese prüft einfach nur, ob die Referenz <> nil ist und ruft ggf. den Destruktor auf.
Objekte die von TComponent erben besitzen einen Parent. Hier kann eine andere TComponent Instanz als Parent übergeben werden. Sollte der Parent zerstört werden, so werden auch alle Kinder zerstört. Weißt du also einer TComponent einen gültigen Parent zu, so brauchst (darfst) du dich nicht mehr um dessen freigabe kümmern, dies übernimmt der Parent für dich.
Bevor du die Instanz einer Klasse freigbist, solltest du immer darauf achten, dass diese nirgendwo mehr in Benutzung ist. Hier kommt wiederum der Fakt zu tragen, dass du hier mit Referenzen arbeitest. Diese Referenzen enthalten nur die zugewiesene Adresse, ist diese ungleich nil, gibt es für dich keine Möglichkeit festzustellen, ob dies eine gültige Referenz ist oder nicht.
Als kurzes Beispiel:
Delphi-Quellcode:
procedure doFoo;
var obj : TObject;
begin
// An dieser Stelle ist der Wert von obj zufällig
// Du kannst hier versuchen auf Eigenschaften von Obj zuzugreifen
// Dabei liest/schreibst du einen zufälligen Speicherbereich, die Folgen
// sind nicht absehbar
// Ist die Adresse zufällig nil, so gibt es eine Access Violation (der Beste Fall!)
// anlegen eines neuen Objekts
obj := TObject.Create;
// nun ist in obj eine gültige Referenz gespeichert
obj.Free;
// Die Instanz die obj referenziert hat wurde frei gegeben
// die Adresse bleibt aber weiterhin gespeichert
// und ist damit gültig
// wieder würden Zugriffe zu Fehlern führen!
obj.Free;
// löst einen Fehler aus!
obj :=
nil;
obj.Free;
// ohne Probleme mögllch
obj.Destroy;
// löst einen Fehler aus!
end;
Dabei kannst du beliebig viele Referenzen auf ein und das selbe Objekt zeigen lassen. Hast du ein grafisches Element, z.B. ein Shape und fügst dies irgendwo ein, wo es angezeigt wird, so speichert diese andere Komponente (die das Shape anzeigt) nur die Referenz auf das Shape. Gibst du nun das Shape frei, wird die Referenz auch weiterhin als gültig betrachtet (da die Adresse ungleich nil ist). Dies führt dann (früher oder später) zu einem Fehler bei der Anzeige. Deshalb musst du die Referenz überall dort, wo du sie einträgst vorher wieder entfernen. Fügst du also ein Shape irgendwo zur Anzeige ein, muss es vor seiner Freigabe dort wieder entfernt werden und darf erst danach frei gegeben werden.
Gruß Der Unwissende