Re: Funktionsrückgabe freigeben
Hallo Angel4585.
Zitat:
Die Frage ist: Wie gebe ich den Speicher frei, den ein Funktion belegt, die ein Objekt zurückgibt? Ich habe den Eindruck, dass du das schon richtig verstanden hast: Zitat:
Zu deinem Beispiel mit der Klasse "TMeinObject": Zunächst mal ist es recht geschickt gemacht! Dadurch entsteht der Eindruck als würdest du auf meine Frage antworten. Die Frage war jedoch: Wie sieht dein "Tu was.." aus, wenn du das OBJEKT aus der Funktionsrückgabe im With-Block benutzen willst. Du hast in deiner Antwort jedoch einfach ein "Unter-Objekt" genommen! Das war NICHT die Frage! Du benutzt innerhalb des With-Blocks ein (Unter-)Objekt des Rückgabe-Objekts. In diesem Fall das Objekt einer Property. Wie gesagt, es war NICHT die Frage, wie ein ein Teil (Property) des Rückgabe-Objekts im With-Block benutzt werden kann, sondern wie das Rückgabe-Objekt selbst im With-Block benutzt werden kann. Um jedoch auf das eigentliche Thema zurückzukommen: Du hast in deinem Beispiel das Icon zwar (leer) erstellt, ihm aber kein Icon zugewiesen. Dadurch werden (fast) keine Ressourcen belegt. Der Sinn einer solchen Funktion ist natürlich, ein Icon auch zu benutzen/füllen. Wenn du das jedoch in deinem "TMeinObject"-Beispiel tust, sind wir so weit wie vorher!
Delphi-Quellcode:
Nun ergibt sich wieder das gleiche Ergebnis: Klickst du vielfach auf den Button, ist im Taskmanager ein langsames aber stetiges Ansteigen der Speicherbelegung zu erkennen!
type
TMeinObject = class(TObject) private FIcon : TIcon; public constructor Create; property ObjectIcon : TIcon read FIcon write FIcon; end; constructor TMeinObject.Create; begin FIcon:=TIcon.Create; end; function IchGebeEinObjectZurueck : TMeinObject; begin Result:=TMeinObject.Create; Result.ObjectIcon.LoadFromFile('C:\Test.ico'); // <- Speicher belegen end; procedure TForm1.Button1Click(Sender: TObject); begin with IchGebeEinObjectZurueck do try // Icon aus Exe auslesen und Image zuweisen Image1.Picture.Graphic := ObjectIcon finally Free; end; end; Aber nun genug davon. Wir haben offensichtlich alle (Thread-Teilnehmer) die Prozedur-Lösung zum Favoriten "erkoren"! Einschließlich dir selbst: Zitat:
Es wurden Möglichkeiten zur Freigabe von Objekt-Funktionsrückgaben in diesem Thread gezeigt. Jedoch können diese nicht wirklich überzeugen. Die Prozedur-Lösung hingegen stellt eine saubere, übersichtliche Möglichkeit dar. Damit ist meine Frage beantwortet. Nochmals danke an alle! Guido. |
Re: Funktionsrückgabe freigeben
beantwortet oder nicht :mrgreen:
es ist egal wie ein Objekt erzeugt wird, ob als Resultat einer Funktion oder einfach so, freigeben muss man es so oder so, also wenn du das Resultat der Funktion einer Variablen zuweist und diese dann freigibst, oder wie ich direkt mit dem With try finally free end arbeitest kommts auf das selbe raus. was ich nicht verstehe ist was es mit der Funktion auf sich hat, ist doch nichts anderes..
Delphi-Quellcode:
Ich nutze die Funktion wenn ich beim Erzeugen eines Objects jedesmal einen Schritt durchführen muss und die Variable selbst jedoch nicht benötige, also nur die "Unterobjekte".
//Das
FIcon:=TIcon.Create; //ist das selbe wie das function Irgendwas : TIcon; begin Result:=TIcon.Create; end; FIcon:=Irgendwas; Zum Beispiel(das verwende ich tatsächlich) wenn ich eine Datenbank anwendung habe und nur eine kurze Abfrage losschicke, dann hab ich nciht eine dauerhafte komponente irgendwo rumliegen, sondern erzeuge meine Query nur wenn ich sie brauche:
Delphi-Quellcode:
Ist jetzt nur ein Beispiel, aber für solche Anwendungen finde ich es einfach praktisch
function MyQuery(ASQL : string) : TZQuery;
begin Result:=TZQuery.Create(nil); Result.Connection:=DataModule1.ZConnection1; Result.SQL.text:=ASQL; end; //Dann spar ich mir dafür an anderen stellen jede Menge Code: with MyQuery('select * from tabelle where id="12345"') do try Active:=True;//Oderd auch Open, ExecSQL etc. //Und dann alles verarbeiten finally Free;//Und die temporäre Query freigeben. end; |
Re: Funktionsrückgabe freigeben
Hallo,
Zitat:
Gruß xaromz |
Re: Funktionsrückgabe freigeben
Hallo xaromz.
Schon lange nichts mehr von dir gehört! Es sei denn, in VB-Kreisen gibt es einen anderen xaromz!? Ansonsten: *freu* Zitat:
@Angel4585 Willst du dich jetzt an dem "Unterobjekt" festbeißen? Dann solltest du wohl einen eigenen Thread aufmachen! In diesem Thread geht es um das komplette Objekt einer Funktions-Rückgabe! Nehmen wir das Beispiel von ganz am Anfang und gestalten es der Klarheit wegen noch ein wenig einfacher:
Delphi-Quellcode:
Wie willst du das mit dem "with try finally free end" lösen? Und bitte, ... BITTE! nicht wieder über irgendwelche Unterobjekte! :wink:
function GetFileIcon(AFileName: string): TIcon;
begin Result := TIcon.Create; Result.LoadFromFile(AFileName); end; procedure TForm1.Button1Click(Sender: TObject); begin // Icon aus Exe auslesen und Image zuweisen Image1.Picture.Graphic := GetFileIcon('C:\Test.ico'); end; Guido. |
Re: Funktionsrückgabe freigeben
Hallo,
Zitat:
Die einzige Möglichkeit wäre hier folgende:
Delphi-Quellcode:
Etwas anderes macht ja with auch nicht, nur dass Du auf die Hilfsvariable nicht explizit zugreifen kannst. Das ist übrigens ein großer Nachteil dieses Konstrukts. Chrome hat das besser gelöst:
procedure TForm1.Button1Click(Sender: TObject);
var Icon: TIcon; begin // Icon aus Exe auslesen und Image zuweisen Icon := GetFileIcon('C:\Test.ico'); try Image1.Picture.Graphic := Icon; finally Icon.Free; end; end;
Delphi-Quellcode:
Gruß
procedure TForm1.Button1Click(Sender: TObject);
begin with Icon := GetFileIcon('C:\Test.ico') do begin Image1.Picture.Graphic := Icon; Icon.Free; end; end; xaromz |
Re: Funktionsrückgabe freigeben
Zitat:
|
Re: Funktionsrückgabe freigeben
IMHO ja, besser wäre da "Assign"
|
Re: Funktionsrückgabe freigeben
Hallo,
Zitat:
Zitat:
Zitat:
Delphi-Quellcode:
Die helper class könnte man noch in eine Bibliotheks-Unit auslagern und wiederverwenden. Die Lösung wirkt aber etwas unsauber und erreicht nicht die Eleganz des Chrome-Konstrukts. Letztlich spart sie nur etwas Schreibarbeit.
type
TObjectHelper = class helper for TObject function Instance: TObject; end; function TObjectHelper.Instance; begin Result := Self; end; procedure TForm1.Button1Click (Sender: TObject); begin // Icon aus Exe auslesen und Image zuweisen with GetFileIcon('C:\Test.ico') do try Image1.Picture.Graphic := TIcon(Instance); finally Free; end; end; Gruß Hawkeye |
Re: Funktionsrückgabe freigeben
Hallo Guido,
Zitat:
Zitat:
Mangels dieses Wissens würde ich es (sicherheitshalber) immer selbst freigeben - wie oben gesagt, wann immer ich dieses Icon nicht mehr brauche. Das kann auch (erst) bei Programmende sein. |
Re: Funktionsrückgabe freigeben
@Angel4585
Noch ein Wort zu meinem vorherigen Post: Als ich das geschrieben habe, war es schon spät und Guido war sehr, sehr müde! Als ich das heute nochmal durchgelesen habe, klang das irgendwie ein wenig hart! Eigentlich wollte ich da noch ein paar Smilies einfügen, um das aufzulockern. Der Leser sieht man ja nicht, wie der Schreiber das meint. Deshalb hier noch die Klarstellung, dass das nicht bös oder sonstwie abweisend gemeint war! :-D @Ingo Danke für Antwort! @xaromz Was ist Chrome? In Delphi geht dieses Konstrukt nicht.
Delphi-Quellcode:
@Hawkeye
procedure TForm1.Button1Click(Sender: TObject);
var Icon: TIcon; begin with Icon := GetFileIcon('C:\Test.ico') do begin Image1.Picture.Graphic := Icon; Icon.Free; end; end; Zitat:
Zitat:
Gruß, Guido. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:31 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