![]() |
function mit TStringList Result
hi DP ,
ich hab mal ne Frage :?: muss ich wenn ich einen Function habe die als Result eine TStringList hat, diesen Result auch wieder freigeben ?
Delphi-Quellcode:
function TForm1.catchItemXML(ItemNr: string): TstringList;
var req : IXMLHTTPRequest; XMLStream:TMemoryStream; XMLStringData:TStringList; EdtUrlText:string; begin try XMLStream:=TMemoryStream.Create; XMLStringData:=TStringList.Create; Result:=TStringList.Create; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Diesen DA req := CoXMLHTTP40.Create; // Interface erzeugen // in EdtURL steht die URL, die heruntergeladen werden soll EdtUrlText:='http://eu.wowarmory.com/item-info.xml?i='+ItemNr ; req.open('GET', EdtUrlText, False, {Username} EmptyParam, {Passwort} EmptyParam); // eigenen Request-Header setzen req.setRequestHeader('ApplicationID', 'Test V1.0'); req.send(EmptyParam); // Anfrage an Server senden und Antwort abwarten // Nutzdaten anzeigen XMLStringData.Text := req.responseText; XMLStringData.Text:= StringReplace(req.responseText,'UTF-8','ISO-8859-1',[rfReplaceAll]); XMLStringData.SaveToStream(XMLStream); XMLStream.Seek(0,soBeginning); Result.LoadFromStream(XMLStream); finally XMLStream.Free; XMLStringData.Free; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Muss der da .free ? oder habe ich sonst keinen result ? end; end; lg bundy |
Re: function mit TStringList Result
Du musst erstmal XMLStringData zurück geben bevor du .Free ausführst.
Jedoch hab ich oft Probleme wenn ich ein Objekt oder in diesem Fall eine Stringlist Free'e. Im Prinzip brauchst du es nicht mal Free'en, denn es ist eine Lokale Variable, diese wird vom Delphi Speichermanager freigegeben. Also:
Delphi-Quellcode:
...
Result:= XMLStringData; end; |
Re: function mit TStringList Result
Dazu gab es schon einmal einen langen Thread hier. An Deiner Stelle würde ich die Stringliste als Parameter übergeben.
|
Re: function mit TStringList Result
aha allso ist es nicht notwendig. ich wusste nur nicht ob mein Result dann noch einen Result hat, wenn ich ihn freigebe.
Delphi-Quellcode:
try result:= ....... finally Result.free; end; danke für die schnelle antwort lg bundy |
Re: function mit TStringList Result
Zitat:
Die Stringlist in der aufrufenden Methode oder als Member anlegen. Dann die Stringlist als Parameter an die Funktion übergeben (evtl. als var-Parameter). Somit brauchst Du Dich in der Funktion nicht um die StringList kümmern -> ein Problem weniger. |
Re: function mit TStringList Result
Var-Parameter sind bei Objekten nicht nötig, da es ja schon Zeiger sind. Ich habe den von mir angesprochenen Thread noch einmal herausgesucht:
![]() |
Re: function mit TStringList Result
Zitat:
Zitat:
Zitat:
Delphi hat keinen Garbage-Kollektor! @bundy: Es wurde schon auf den Diskussions-Thread verwiesen und den empfehle ich auch. Grundlegend sollte man alloziierten Daten auf der gleichen Ebene wieder freigeben wie sie alloziiert wurden. Somit solltest du deine TStringList auch in der Procedure/Methode freigeben, was du aber nicht kannst, da sonst dein Rückgabewert weg wäre. Somit wäre die sauberste Lösung, dass du die TStringList aussen anlegst und beim Aufruf übergibst. Dann hast du erst gar nicht das Problem darüber nachdenken zu müssen.
Delphi-Quellcode:
Und der Aufruf dann:
function TForm1.catchItemXML(ItemNr: string; const AList: TStrings): TstringList;
var req : IXMLHTTPRequest; XMLStream:TMemoryStream; XMLStringData:TStringList; EdtUrlText:string; begin XMLStream:=TMemoryStream.Create; XMLStringData:=TStringList.Create; try req := CoXMLHTTP40.Create; // Interface erzeugen // in EdtURL steht die URL, die heruntergeladen werden soll EdtUrlText:='http://eu.wowarmory.com/item-info.xml?i='+ItemNr ; req.open('GET', EdtUrlText, False, {Username} EmptyParam, {Passwort} EmptyParam); // eigenen Request-Header setzen req.setRequestHeader('ApplicationID', 'Test V1.0'); req.send(EmptyParam); // Anfrage an Server senden und Antwort abwarten // Nutzdaten anzeigen XMLStringData.Text := req.responseText; XMLStringData.Text:= StringReplace(req.responseText,'UTF-8','ISO-8859-1',[rfReplaceAll]); XMLStringData.SaveToStream(XMLStream); XMLStream.Seek(0,soBeginning); AList.LoadFromStream(XMLStream); finally XMLStream.Free; XMLStringData.Free; end; end;
Delphi-Quellcode:
Und nochwas: Beachte die vom Compiler generierten Hinweise und Warnungen, sie sind nicht unwichtig! Du hast in deinem originalen Code hinweise, dass die Elemente XMLStream und XMLStringData möglicherweise nicht initialisiert worden seien. Damit hat Delphi auch vollkommen Recht! Also beachte die Hinweise!
var
lList: TStrings; begin ... lList := TStringList.Create; try catchItemXML('deinItem', lList); ... mach was mit lList... ... finally lList.Free; end; end; Hintergrund: Du hast die Konstruktorenaufrufe innerhalb des try/finally Blockes gemacht und damit würde er mit einer Exception in einem der beiden Konstruktoren in den finally Teil springen. Damit aber würde er im Finally teil den Destruktor aufrufen von zwei Instanzen die gar nicht existieren. Die Assigned() Prüfung im .Free greift nicht, da es beides lokale Variablen sind und diese somit zufälligen Inhalt haben und somit zufällige Adressen. Sie sind bei gut Glück zufälligerweise Nil, aber das ist pures Glück und ist sehr unwahrscheinlich. |
Re: function mit TStringList Result
Zitat:
Aber var-Parameter erhöhen die Übersichtlichkeit. Man sieht sofort in der Deklaration, dass hier etwas zurückgegeben wird. Und das eine Wort tut auch keinem weh, vermutlich optimiert der Compiler das eh weg. |
Re: function mit TStringList Result
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:12 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz