Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Frage zu FreeAndNil (https://www.delphipraxis.net/147947-frage-zu-freeandnil.html)

DelTurbo 19. Feb 2010 14:40


Frage zu FreeAndNil
 
Hi,

ist das nicht egal ob ich object.free; mache oder FreeAndNil(object)? Die sachen liegen auf dem stack. Das letzte command bevor die sub verlassen wird, ist object.free;

Macht es sinn sachen die nicht auf dem stack liegen mit FreeAndNil freizugeben? Macht das nicht auch nur ein .free und dann object:=nil?

Danke im voraus

Neutral General 19. Feb 2010 14:45

Re: Frage zu FreeAndNil
 
Lokale Objektvariablen die am Ende der Methode/Prozedur freigegeben werden sollen brauchen kein FreeAndNil.

FreeAndNil ist eigentlich nur notwendig, wenn du einer Objektvariable im Laufe der Zeit immer neue Objekte zuweist um nachschauen zu können, ob gerade ein Objekt zugewiesen ist oder nicht.

DelTurbo 19. Feb 2010 14:49

Re: Frage zu FreeAndNil
 
Ah, danke. Wieder was gelernt :) Dann kann ich ja alles so lassen. Weil nach nil frage ich nirgends ab.

Luckie 19. Feb 2010 15:50

Re: Frage zu FreeAndNil
 
Ich habe mir aber trotzdem angewöhnt FreeAndNil zu benutzen, dann ist man immer auf der sicheren Seite.

himitsu 19. Feb 2010 15:59

Re: Frage zu FreeAndNil
 
Wenn man irgendwo prüft, ob das Objekt existiert, z.B. ala if assigned(obj) then, dann muß man die Variable nach dem Freigeben auch auf NIL setzen.

dieses gibt nur frei
Delphi-Quellcode:
obj.Free;
dieses würde zwar theoretisch auf NIL setzen, aber wenn es beim .Free zu einer Exception kommt, dann gibt es später womöglich nette Probleme
Delphi-Quellcode:
obj.Free;
obj := nil;
also macht sich Dieses dann schon besser, weil es erst auf NIL setzt und danach .Free aufruft
Delphi-Quellcode:
FreeAndNil(obj);

DelTurbo 19. Feb 2010 16:04

Re: Frage zu FreeAndNil
 
Hmmm, denn frag ich mal gezielter.

Was macht FreeAndNil? Mehr als

Delphi-Quellcode:
object.free;
object:=nil;
mach es doch nicht, oder testet der noch irgendwas? Weil wenn nicht, ist es in meinem falls wurscht, da es auf dem stack liegt und nachdem ret eh nimmer verfügbar ist.

EDIT: da war himitsu schneller :P

himitsu 19. Feb 2010 16:29

Re: Frage zu FreeAndNil
 
Zitat:

Zitat von DelTurbo
EDIT: da war himitsu schneller :P

:tongue:

Strg + Linksklick auf FreeAndNil
Delphi-Quellcode:
procedure FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;
was logisch gesehn in etwa Diesem entsprechen würde
Delphi-Quellcode:
procedure FreeAndNil(Obj: TObject);
begin
  try
    Obj.Free;
  finally
    Obj := nil;
  end;
end;

thkerkmann 19. Feb 2010 17:39

Re: Frage zu FreeAndNil
 
Zitat:

Zitat von himitsu
was logisch gesehn in etwa Diesem entsprechen würde
Delphi-Quellcode:
procedure FreeAndNil(Obj: TObject); <<<<<< fehlt hier ein VAR
begin
  try
    Obj.Free;
  finally
    Obj := nil;
  end;
end;

das VAR bei dieser Parameterübergabe ist aber eintscheidend. Sonst wird das if Assigned(obj) wieder nix :drunken:

mjustin 19. Feb 2010 17:59

Re: Frage zu FreeAndNil
 
Zitat:

Zitat von DelTurbo
Macht es sinn sachen die nicht auf dem stack liegen mit FreeAndNil freizugeben? Macht das nicht auch nur ein .free und dann object:=nil?

Was eh nicht mehr benutzt wird, z.B. was im Destruktor freigegeben wird, benötigt kein FreeAndNil:

Eine schöne, lange Diskussion dazu hier:

"FreeAndNil is often sign of wrong design - did anyone really read the blog?"
https://forums.embarcadero.com/threa...threadID=32623

Viele Grüße,

negaH 19. Feb 2010 18:23

Re: Frage zu FreeAndNil
 
Darüber lässt sich streiten.

Szenario:

Ein Objekt verwaltet mehrere Objektvariablen als Felder in sich selbst. Alle diese Objekte greifen über einen zb. Owner/Parent auf diese übergeordnete Objekt zu. Diese untergeordneten Objekte nutzen ihren Owner/Parent um ihrerseits auf die anderen Objekte des Parten/Owners zugreifen zu können. Soweit ein ganz legales und OOP konformes Konstrukt.

Der Parent kann nun nicht zum gleichen Zeitpuinkt seine Objektfelder freigeben, er wird es immer sequentiell ausführen müssen.
Die untergeordneten Objekte des Parents fragen ihrerseits mit Assigned(Parent.Objekt_A) bei einem Zugriff ab ob das gewünschte Objekt überhaupt erzeugt wurde.

Nun passiert es gerade bei komplexeren Klassenstrukturen wie zb. Windows Controls das ein asynchrones Messagehandling benutzt wird. Also selbst beim Freigeben eines spezifischen Objektes kann es durchaus sein das dieses über Parent.Objekt_A noch weitere Behandlungen durchführt. Würde man im Destructor des parents nun njicht mit FreeAnNil() die Objekte freigeben dann funktioniert bei der Freigabe des nachfolgenden Objektes (Objekt_B im Parent) eine Abfrage wie Assignend(Parent.Objet_A) nicht korrekt.

Man kann nun behaupten das das alles "schlechtes Design" wäre.

Ich stehe auf folgendem Standpunkt:

1.) mache gutes Design
2.) benutzte ein zusätzlich Sicherheitsnetz, das kann nie schaden und kostet nichts

Wer von sich behauptet er benötigt kein
- FreeAndNil()
- if Assigned() then
- if Objekt is Klasse then

weil sein Design immer ein gutes Design ist das dies ja nicht nötig hat, der hat noch nie im Team gearbeite, noch auf Sourcen/Code anderer Programmierer aufsetzten, weiterentwickeln müssen und ist ergo arrogant und fern der Realitäten.

Gruß Hagen

PS: oder er benutzt eine Programmiersprache bei der all diese Probleme erst garnicht auftreten können, wozu Delphi nunmal nicht gehört.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:01 Uhr.
Seite 1 von 3  1 23      

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