Frage

Wenn ein Objekt, das innerhalb einer Funktion und die Funktion erstellt wird, abgeschlossen ist, was mit dem Objekt passiert, wenn es nicht explizit zerstört wurde?

Sind alle Variablen zerstört werden müssen, wenn sie außerhalb des Bereichs fallen oder sie getroffen werden betreut, wenn sie außerhalb des Bereichs fallen?

So zum Beispiel, was passiert dann mit locallist nach custom_function aufgerufen wurde?

function TForm1.custom_function(string: test_string): boolean;
var locallist: TStringList;
begin
  locallist := TStringList.Create;
  // do a bunch of stuff here, but don't destroy locallist
  return true;
end;
War es hilfreich?

Lösung

Sie einen Speicherverlust bekommen.

Die richtigen Muster

myObject := TObject.Create;
try
  //do stuff
finally
  myObject.Free;
end;

Auch wenn Sie später testen müssen, wenn das Objekt freigegeben wurde, dann verwenden FreeAndNil (myObject). Es wird die Variable auf Null als auch, so dass Sie es später testen können.

Andere Tipps

Wie die anderen Plakate erwähnt, müssen diese Objekte explizit freigegeben werden. Dies wird in der Regel von Hand durch die Verwendung eines try..finally Block durchgeführt, wie Ray demonstriert. Es gibt Ausnahmen, aber, dass Sie sich bewusst sein sollte.

Die Komponenten (TComponent Nachkommen) einen Parameter Owner an ihren Konstruktor übergeben. Wenn der Eigentümer nicht ist gleich Null , dann wird die Eigentümer Komponente Eigentum an die neuen Komponente übernimmt und es, wenn es freigegeben wird. Aus diesem Grund müssen Sie Ihre eigenen Formulare nicht aufzuräumen; sie sind mit dem Application-Objekt verbunden ist, der weiß, wie man frei selbst , wenn das Programm fertig ist. Wenn Sie eine Komponente zur Laufzeit jedoch erstellen, müssen Sie entweder einen Besitzer zuweisen oder geben nil an den Konstruktor und es dann selbst befreien. Sie die beiden nicht mischen, indem eine Komponente mit einem Eigentümer zu befreien. Das kann ein Doppelfreien Zustand unter bestimmten Umständen verursachen.

Angeschlossen Objekte, die Referenzzählung implementieren (TInterfacedObject Nachkommen, meist) durch den Referenz Zählmechanismus befreit werden, wenn Sie sie speziell als Schnittstelle beziehen (nicht als Objekt.) Sie erhalten automatisch freigegeben, wenn die letzte Schnittstelle ihnen Referenz entfernt. Verwenden Sie keine TInterfacedObject manuell befreien, wenn Sie es bereits mit einer Schnittstelle Referenz zugewiesen haben. Dies wird eine Ausnahme ausgelöst. Beachten Sie auch, dass nicht alle Objekte mit Schnittstellen Referenzzählung implementieren. Meistens nur diejenigen, die von TInterfacedObject abstammen.

Es ist nicht immer praktisch, ein Objekt zu erstellen, einen try..finally Block verwenden, und befreien Sie es dann. Manchmal ist das einfach nicht funktioniert, was Sie tun, vor allem, wenn Sie das Objekt eine Art Liste sind zuweisen (und eine ganze Menge von ihnen zu machen.) In diesem Fall ist es eine gute Idee, einen TObjectList zu verwenden ( oder noch besser, wenn Sie D2009, ein TObjectList) mit der OwnsObjects Eigenschaft auf true . Dies bewirkt, dass die Liste der Besitzer der Objekte darin werden, und sie zu befreien, wenn es befreit wird, ebenso wie Komponenten tun. Auch hier nicht manuell ein Objekt freizugeben, wenn sie von einer Objektliste im Besitz ist.

Dynamische Arrays (einschließlich Strings) werden vom Compiler mit einem Referenzzähler-System verwaltet, und die meisten anderen Arten von Variablen werden auf dem Stack zugeordnet. Sie müssen sich nie über das manuelle Sorgen etwas anderes als Objekte zu befreien, es sei denn, Sie mit Zeiger gerade spielen um.

Das klingt vielleicht kompliziert, aber Sie werden es früh genug zu gewöhnen. Denken Sie daran, dass jedes Objekt durch einen von drei Dingen gehört: eine weitere Aufgabe, das Interface-Referenz-Zählsystem, oder Ihr Code, und der Besitzer sollte alle seine Objekte freigeben, wenn sie nicht mehr gebraucht werden. Nichts sollte frei, etwas auszuprobieren, die durch etwas anderes im Besitz ist. (Du sollst nicht stehlen.) Denken Sie daran, diese Richtlinien, und Sie werden mit einer guten Speicherverwaltung enden. Sie können auch einstellen.: In der Hauptroutine für ein bisschen mehr Hilfe in Ihrer DPR „ReportMemoryLeaksOnShutdown = true“

Es wird durchgesickert Speicher.

Sie sollten in der Regel solche Zuteilungen umgeben so:

locallist := TStringList.Create;
try
     // work with locallist here
  finally
     locallist.Free;
  end; 

Die einzige Art von Referenzen in Delphi, die selbstmörderisch sind, wenn sie außerhalb des Bereichs fallen sind Interface-Referenzen.

Der Speicher nicht freigegeben wird, sorry. Sie müssen dieses Objekt explizit frei mit locallist.Free;

Dies führt zu einem Speicherleck , die nur am Ende der zerstört werden Anwendung. Um festzustellen, diejenigen, können Sie einen Speicher Manager verwenden, wie FastMM .

Beachten Sie, dass Objekte zerstören können entweder über die zerstören oder die Methode Free. Der erste wird einen Fehler geben, wenn das Objekt null ist, letztere wird nicht - es ist gleich

if Assigned(Object) then Object.Destroy;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top