![]() |
TObjectlist.add(record)?
Hallo zusammen,
ich möchte zu einer TOjectlist ein Record hinzufügen und bekomme immer einen Typenkonverierungsfehler.
Delphi-Quellcode:
Wie kann ich das Problem umgehen?
type TCLCategory = record
id:integer; Category:string; parent:integer; end; type TMyClass = class (TComponent) private FCategory: TObjectList; .... procedure TMyClass.irgendetwas; var current:TCLCategory; begin .... FCategory.Add(Current); <-hier ... end; |
Re: TObjectlist.add(record)?
Hallo.
Um Records zu verwalten solltest du nicht TObjectList nehmen. Nimm TList und beachte, dass du einen Zeiger (@Current) übergeben musst. Grüße vom marabu |
Re: TObjectlist.add(record)?
Gaaaannnz schlimm. :shock:
current ist eine lokale Variable! Diese ist nach verlassen der Procedure nicht mehr gültig. Du kanst nicht mit Records in Listen arbeiten. Da must du schon ein Object draus machen und artig instanzieren. Freigeben nicht vergessen. Aber da kann dir TObjectList mit ownsobjects=true helfen. Gerd |
Re: TObjectlist.add(record)?
Danke Marabu!
Ich habe es mit jetzt TList gemacht.Nur der Vollständigkeit, wie wäre es mit TObjectlist, auch wenn es nicht sauber ist? Danke! @bernau Danke für den Tipp.Hast du dazu ein Code-Snippet? Irgendwie stehe ich auf dem Schlauch. |
Re: TObjectlist.add(record)?
Mit record kann man sehr wohl arbeiten, genauer gesagt mit den Pointers auf Record.
Delphi-Quellcode:
type
TForm1 = class(TForm) Button1: TButton; ListBox1: TListBox; procedure Button1Click(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } public { Public declarations } List:TList; procedure AddItem( NewItem:pointer); end; var Form1: TForm1; implementation {$R *.dfm} type PmyRec = ^TmyRec; TmyRec = record item1:Integer; item2:Byte; item3:string; // vorsicht ;) end; procedure TForm1.AddItem(NewItem: pointer); begin with PmyRec( NewItem )^ do begin ListBox1.Items.Add( IntToStr( item1 )); ListBox1.Items.Add( IntToStr( item2 )); ListBox1.Items.Add( item3 ); end; end; procedure TForm1.Button1Click(Sender: TObject); var newRec : PmyRec; i:Integer; begin Randomize(); if not Assigned(List) then begin List := TList.Create; end; for i:=0 to 10 do begin New( newRec ); with newRec^ do begin item1 := random(100); item2 := random(255); item3 := 'hallo'; end; List.Add( newRec ); AddItem( newRec ); end; end; procedure TForm1.FormDestroy(Sender: TObject); var i:Integer; rec:PmyRec; begin for i:= List.Count-1 downto 0 do begin rec := PmyRec ( List.Items[i] ); rec^.item3 := ''; List.Delete(i); Dispose(rec); end; List.Free(); end; |
Re: TObjectlist.add(record)?
Guten Morgen sniper_w!
Danke für dein sehr ausfühliches Beispiel. Ich habe es etwas anders gemacht, aber ich lerne immer gern dazu. :idea: |
Re: TObjectlist.add(record)?
Zitat:
Marabu hat sich in seinem Beispiel aber auf die Variable "current" bezogen. Dies ist eine lokale Variable in der Procedure, die nach Beendigung der Procedure schlicht nicht mehr vorhanden ist und somit der Zeiger ins Nirvana zeigt. Dumm ist, daß die Belegung des Speichers (da wo der Pointer hinzeigt) tatsächlich noch eine Zeit lang so ist wie Sie sein sollte. Aber irgendwann wird dieser Speicherbereich von anderen Daten überschrieben. Darauf wollte ich nur aufmerksam machen, bevor stundenlang nach Fehlern gesucht wird. Übrigens finde ich es eleganter mit Objekten zu arbeiten statt mit Pointern auf Records. Aber das ist reine Geschmackssache. Gerd |
Re: TObjectlist.add(record)?
Zitat:
Zitat:
Hier mal eben schnell zusamengeschrieben:
Delphi-Quellcode:
type TCLCategory = class (TObject) // <- kein record sondern ein Object
id:integer; Category:string; parent:integer; end; type TMyClass = class (TComponent) private FCategory: TObjectList; .... procedure TMyClass.create; begin FCategory:=TObjectList.create; FCategory.ownsobjects:=true; end; .... procedure TMyClass.irgendetwas; var current:TCLCategory; begin .... current:=TCLCategory.create; // Hier die Were zuweisen current.Category:='Irgendein String'; FCategory.Add(Current); ... end; |
Re: TObjectlist.add(record)?
Zitat:
|
Re: TObjectlist.add(record)?
Hallo Leute,
mein Beitrag #2 war wohl Auslöser für eine heiße Diskussion ganz nach dem Vorbild Shakespeare's Much Ado about Nothing: Der Klammerzusatz (@Current) war nur ein missglückter Versuch meinen allgemein gehaltenen Beitrag doch noch etwas in Bezug zum Code von ozz zu setzen. Wer mir zutraut, ich würde die Adresse einer Variablen auf dem Stack mit der Adresse einer Variablen auf dem Heap verwechseln, der kränkt mich. Aber Gerd hat sicherlich recht mit seinem Hinweis - wer weiß wen ich sonst noch alles ungewollt aufs Glatteis schicke. Der Speicher für lokale Variablen einer Funktion oder Prozedur wird vor dem Aufruf des Codes durch Verschieben des stack pointers bereit gestellt. Nach der Rückkehr aus der Funktion wird dieser Speicher wieder zur Verfügung gestellt. Bei erneutem Aufruf der Funktion kurz danach kann es passieren, dass man auf die alten Inhalte zugreifen kann. Generell wird dieser Speicherbereich aber bei Bedarf wieder von anderen Routinen verwendet. Will ich selbst die Lebensdauer des Speichers bestimmen, dann muss ich den Speicher entweder über globale Variablen bereit stellen oder ich verwalte den Speicher über die entsprechenden Funktionen auf dem Heap. @sniper_w: eigentlich war ich davon überzeugt, dass dein Code-Beispiel die Dinge bereits ausreichend beleuchtet hatte, aber dein letzter Beitrag hat mich dann doch noch zu einem beherzten Griff in die Tasten bewogen. Freundliche Grüße vom marabu |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:55 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