![]() |
Erzeugen und Freigeben von Objekten und Speicher
Ich hätte einmal eine grundsätzliche Frage zu Objekten.
Ich möchte die Objects Eigenschaft des StringGrid verwenden, um zusätzliche Formatierungsoptionen für die einzelne Zelle zu speichern. Ggf. soll über die neue Eigenschaft IsBitmap auch eine Grafik angezeigt werden können. Hier einmal eine beispielhafte Deklaration des Objektes für die Eingenschaften:
Delphi-Quellcode:
Hier wäre jetzt die Zuweisung an jede Zelle des StringGrid:
type
TCellOption = class(TObject) public Font: TFont; IsBitmap: Boolean; Bitmap: TBitmap; end; ...
Delphi-Quellcode:
Jetzt kann ich allerdings noch nichts an Font zuweisen, weil ja noch keine Instanz davon erzeugt wurde, also könnte es so aussehen:
ACellOption:=TCellOption.Create;
StringGrid.Objects[..]:=ACellOption;
Delphi-Quellcode:
Genauso wird dann auch mit Bitmap verfahren nur zunächst ohne ein Bitmap zuzuweisen, da es ja nicht in jeder Zelle unbedingt benötigt wird.
ACellOption:=TCellOption.Create;
ACellOption.Font:=TFont.Create; ACellOption.Font.Assign(Font); StringGrid.Objects[..]:=ACellOption; Erste Frage: Wenn ich die so erzeugten Objekte wieder freigeben möchte, welche Methoden muss ich dann aufrufen? StringGrid.Objects[..].Free? Damit ist die Instanz von TFont aber noch nicht freigegeben, oder? Sollte ich also geschickterweise die create und destroy-Methoden von TCellOption überschreiben und darin die Instanz von TFont (und TBitmap) erzeugen und freigeben? Zweite Frage: Wie verhält es sich mit dem Speicherbedarf, wenn ich direkt eine Instanz von TBitmap pro Zelle erzeuge, ohne das ich sie evtl. wirklich benötige? Danke und Gruß, Guido |
Re: Erzeugen und Freigeben von Objekten und Speicher
Hallo Guido,
du brauchst einen eigenen Destruktor, wenn das Objekt Eigentümer z.B. des Font sein soll. Anders wäre es, wenn nur eine Referenz gespeichert würde. Was die Bitmap angeht: Probiere es einfach aus und messe den Verbrauch, dann weißt du wie skalierfähig dein Ansatz ist. Oft verwaltet man Bilder in einer ImageList und setzt beim Objekt nur eine Referenz, aber das musst du erkennen. Grüße vom marabu |
Re: Erzeugen und Freigeben von Objekten und Speicher
Zitat:
Zitat:
Zitat:
Zitat:
Eingebettete Objekte werden dabei nicht berücksichtigt (bzw. nur 4 Bytes für den Objektzeiger). Ein gefülltes Bitmap benötigt dann noch zusätzliche Resourcen. |
Re: Erzeugen und Freigeben von Objekten und Speicher
Zitat:
hier gibt es schon die erste Stelle an der Du aufpassen solltest. Wenn Du mit Create eine neue Instanz erzeugst, dann wird Dir eine Referenz auf dieses neue Objekt zurück gegeben. Genau diese Referenz wird in ACellOption.Font gespeichert. Weißt Du hier einer TCellOption zweimal einen Font zu, so überschreibst Du nur die alte Referenz. Das Objekt, dass Du angelegt hast würde einfach im Speicher bleiben (und wäre nicht mehr erreichbar). Besser ist es hier, dass Du vorher ein Free aufrufst um sicherzustellen, dass es keine erste Instanz gibst, die sonst ein Speicherleck darstellt. Zitat:
Zitat:
Zitat:
An sich wäre eventuell eine gute Möglichkeit für Dich, dass Du die Zuweisung über Properties vornimmst. Die erlauben es Dir, dass Du eben Speicher nur bei Bedarf zuweist. Grob könnte es die folgende Form haben:
Delphi-Quellcode:
Die Implementierung könnte dann so aussehen:
TCellOption = class(TObject)
private FFont: TFont; Bitmap: TBitmap; protected procedure setBitmap(const Bitmap: TBitmap); procedure setFont(const Font: TFont); public destructor Destroy; override; function hasBitmap(): Boolean; property Bitmap: TBitmap read FBitmap write setBitmap; property Font: TFont read FFont write setFont; end;
Delphi-Quellcode:
Gruß Der Unwissende
destructor TCellOption.Destroy;
begin self.FBitmap.Free; self.FFont.Free; inherited Destroy; end; function TCellOption.hasBitmap: Boolean; begin result := assgigned(self.FBitmap); end; procedure TCellOption.setBitmap(const Bitmap: TBitmap); begin if assigned(Bitmap) then begin // wenn self.FBitmap nichts zugewiesen ist // wird einen neue Instanz erzeugt if not assigned(self.FBitmap) then begin self.FBitmap := TBitmap.Create; end; self.FBitmap.Assign(Bitmap); end // wenn dem TBitmap-Objekt nil zugewiesen wird, dann wird die Bitmap einfach gelöscht else begin self.FBitmap.Free; self.FBitmap := nil; end; end; // analog für setFont [roter Kasten] Ok, das meiste hier wurde schon gesagt, aber ich poste es mal trotzdem! [/roter Kasten] |
Re: Erzeugen und Freigeben von Objekten und Speicher
Danke für die Antworten! Ich bin ja anscheinend auf dem richtigen Weg und werde die hier erhaltenen Informationen mal in ein paar Versuchen verwerten.
Kurze Nachfrage noch: Was bewirken denn self.FBitmap oder self.FFont.Free ? Wo liegt der Unterschied zu FFont.Free? Danke. |
Re: Erzeugen und Freigeben von Objekten und Speicher
Zitat:
|
Re: Erzeugen und Freigeben von Objekten und Speicher
Ich würde bereits im constructor von TCellOption eine Instanz von Font und Bitmap erstellen, und diese im Destructor natürlich auch wieder freigeben.
So kann von aussen, nach Erstellen einer TCellOption Instanz direkt auf dessen Font und Bitmap zugegriffen werden, ohne eine Zugriffsverletzung zu bekommen. |
Re: Erzeugen und Freigeben von Objekten und Speicher
Da es gut zum Thema passt, noch eine Frage hinterher:
Wenn ich eine Instanz mit Create(AOwner) erzeuge muss ich dies dann wieder explizit Freigeben oder erlegigt das der Owner automatisch, wenn er freigegeben wird? z.B. Erstelle ich auf einem Formular eine x-beliebige Komponente:
Delphi-Quellcode:
Ist dann in TForm1.Destroy noch notwendig Panel.Free aufzurufen?
procedure TForm1.Create;
begin Panel:=TPanel.Create(self); Panel.Parent:=Form1; end; |
Re: Erzeugen und Freigeben von Objekten und Speicher
Hallo,
durch das .(Self) wird das Form der Owner und gibt das Panel auch frei. Ich empfehle memcheck, um Speicherfehler zu finden. Heiko |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:26 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