Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Viele Objekte ordentlich(!) erstellen (https://www.delphipraxis.net/144915-viele-objekte-ordentlich-erstellen.html)

TheMiller 19. Dez 2009 18:51


Viele Objekte ordentlich(!) erstellen
 
Hallo,

hab ein etwas kurioses Problem. Ich vermute, es liegt daran, wie ich die Objekte erstelle - es ist noch etwas Neuland für mich.

Also, ich habe mehrere Klassen: Kategorie-Klasse, Artikel-Klasse und eine Kategorien-Klasse (sie enthält alle Kategorien). Jedem Kategorie-Objekt kann man mehrere Artikel-Objekte hinzufügen.

Mein Quelltext sieht demnach so aus:

Delphi-Quellcode:
procedure TForm1.UpdateList;
var
  i,j: Integer;
  Item, Parent: TTreeNode;
  expanded: TIntArray;
  Kategorie: TKategorie;
  Artikel: TArtikel;
begin
  //Root-Kategorie (ID: -1) erstellen
  Kategorie:=TKategorie.Create;
  Kategorie.ID:=-1;
  KomKats.Add(Kategorie); //Typ: TKategorien Mehrzahl(!)
  Kategorie:=nil;
  //...
  while not (Form1.ZQuery1.Eof) do
  begin
    Kategorie:=TmKategorie.Create;
    Kategorie.ID:=Form1.ZQuery1.FieldByName('katid').AsInteger;
    Kategorie.Titel:=Form1.ZQuery1.FieldByName('titel').AsString;
    Kategorie.ChildFrom:=Form1.ZQuery1.FieldByName('parent').AsInteger;
    KomKats.Add(Kategorie);
    Form1.Zquery1.Next;
  end;
 
  //...
  while not (Form1.ZQuery1.Eof) do
  begin
    Artikel:=TArtikel.Create;
    Artikel.ID:=Form1.ZQuery1.FieldByName('ARTIKELID').AsInteger;
    Artikel.Titel:=utf8encode(Form1.ZQuery1.FieldByName('TITEL').AsString);
    Artikel.Kategorie:=Form1.ZQuery1.FieldByName('KID').AsInteger;
    KomKats.Kategorie[KomKats.getIndexById(Artikel.Kategorie)].AddArtikel(Artikel);
    Form1.ZQuery1.Next;
  end;

  //...
  //Kategorie-Objekte durchgehen und diese inkl. dessen Artikel im TreeView anzeigen.
end;
Sodele... Dieser Code hat mal funktioniert, bis ich die in der SQL-Query das "ORDER-BY"-Kriterium geändert habe. Seitdem kamen AVs. Habe ich das ORDER-BY wieder hinzugefügt, hat es wieder funktioniert.
Ich denke, ich mache einen Fehler beim Objekte erstellen und Objekte (nicht-)freigeben. Zumal es bei dieser Lösung so ist, dass jede Kategorie den Titel der ersten Kategorie hat. So denke ich, ich muss das Kategorie-Objekt "löschen" und ein neues erstellen, wenn ein neuer Datensatz geladen wurde (in der while-Schleife).

Bitte gebt mir Tipps und sagt mir, was ich falasch mache!

Vielen Dank

sx2008 19. Dez 2009 18:57

Re: Viele Objekte ordentlich(!) erstellen
 
Schau Dir mal dieses Codeschnipsel an:
Delphi-Quellcode:
KomKats.Kategorie[KomKats.getIndexById(Artikel.Kategorie)].AddArtikel(Artikel);
Daraus würde ich dies machen:
Delphi-Quellcode:
kat := KomKats.FindKategorieByName(Artikel.Kategorie);
if not Assigned(kat) then
  ShowMessageFmt('Kategorie %s nicht gefunden',[Artikel.Kategorie])
  // hier könnte auch eine Exception statt ShowMessage stehen
else
  kat.AddArtikel(Artikel);
PS:
du schreibst überall Form1.[irgendwas].
Lass das Form1. mal weg, denn es schadet nur.

TheMiller 19. Dez 2009 19:46

Re: Viele Objekte ordentlich(!) erstellen
 
Vielen Dank.

Das Form1. habe ich nur bei der ZEOS-Komponente. Ist so eine Angewohnheit - sonst, bei anderen Komponenten mache ich das nicht.

Das mit den Objekten erstellen mache ich aber richtig? Ich muss nicht in jedem Durchlauf ein neues Objekt erstellen und am Ende auch nicht freigeben - es verschwindet sonst nämlich auch aus der Object-List (Kategorien).
Wenn das so richtig ist, wie bekomme ich es dann hin, dass im nächsten Durchlauf das Objekt mit allen Eigenschaften wieder "geleert" ist und so nicht fälschlicherweise Daten eingetragen werden, die vom vorherigen Durchlauf kommen.

Ist doof beschrieben - ich hoffe ihr wisst, was ich meine!

Danke im Voraus

sx2008 19. Dez 2009 20:06

Re: Viele Objekte ordentlich(!) erstellen
 
Wichtig ist, wer den "Besitz" (Ownership) über die Objekte übernimmt.
Das Objekt, das den Besitz über ein anderes übernommen hat ist verantwortlich für die Freigabe.
Es darf nur einen Besitzer geben.
Gibt es keinen Besitzer entsteht ein Speicherleck; gibt es mehr als einen folgt eine mehrfache Freigabe.
Die Klasse TObjectList hat im Constructor Create() einen Parameter, der angibt, ob der Besitz übernommen werden soll.
Bei den Objekte der Klasse TKategorie wäre der Besitzer "KomKats" (class(TKategorien)).

Bei den Artikel wird das schon schwieriger.
Ein Artikel könnte mehreren Kategorien angehören.
Wenn dies der Fall ist, kann die Klasse TKategorie nicht den Besitz über die Artikel übernehmen, sondern es müsste dann ein separate Artikelliste geben.
Diese Artikelliste könnte von "KomKats" geführt werden.

Zitat:

Zitat von DJ-SPM
wie bekomme ich es dann hin, dass im nächsten Durchlauf das Objekt mit allen Eigenschaften wieder "geleert" ist und so nicht fälschlicherweise Daten eingetragen werden, die vom vorherigen Durchlauf kommen.

Das kann gar nicht passieren, schlieslich erzeugst du in jedem Durchlauf ein neues Objekt.
Dieses Objekt hat keine Daten vom Vorgänger.

TheMiller 19. Dez 2009 21:03

Re: Viele Objekte ordentlich(!) erstellen
 
Ok, dann mach ich das ja soweit richtig. Das freut mich. Das die Object-List den Besitz übernimmt, dass wusste ich - genauso wie sie die Objekte wieder freigibt.

Wobei ich mir nicht sicher war, ist die Stelle, an der die neuen Objekte erzeugt werden. Immerhin ist es immer die gleiche Variable, die zudem auch nicht freigegeben wird - das hat mich etwas verwirrt... ;)

Was die "Mehrfachwerte" angeht: Da habe ich wohl einen "Anzeigefehler".

Nur weis ich nicht, woher diese blöde AV kommt... Auch durch Breakpoints setzen und debuggen konnte ich es nicht herausfinden. Mal hier, mal da...

Bin aber grad nicht am PC, schaue "Schlag den Raab" ;)

Vielen Dank für eure Hilfe!

TheMiller 20. Dez 2009 10:26

Re: Viele Objekte ordentlich(!) erstellen
 
Hallo,

ich habe den Fehler mit der AV gefunden. Den hätte keine finden können - er hing mit den Daten aus der Datenbank zusammen.

Aber immerhin bin ich jetzt um einiges schlauer, was die OOP betrifft.

Vielen Dank!


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:19 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