Zitat von
guidobrose:
Jetzt kann ich allerdings noch nichts an Font zuweisen, weil ja noch keine Instanz davon erzeugt wurde, also könnte es so aussehen:
Delphi-Quellcode:
ACellOption:=TCellOption.Create;
ACellOption.Font:=TFont.Create;
ACellOption.Font.Assign(Font);
StringGrid.Objects[..]:=ACellOption;
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.
Hi,
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 von
guidobrose:
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?
Korrekt!
Zitat von
guidobrose:
Sollte ich also geschickterweise die create und destroy-Methoden von TCellOption überschreiben und darin die Instanz von TFont (und TBitmap) erzeugen und freigeben?
Ja!
Zitat von
guidobrose:
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?
Du hast einen recht geringen Speicherbedarf. Das was ein Bitmap-Objekt wirklich groß macht ist die eigentliche Bitmap (das Bild). Ein TBitmap-Objekt besteht aus ein wenig mehr, so hast Du halt die Meta-Informationen einer Bitmap (Höhe, Breite, Farbtiefe, ...) und ein wenig
VCL-Overhead (
Handle, Pen, Brush, Canvas,...) aber an sich sollten dass nur ein paar zig oder hundert Byte sein. Das eigentlich große kommt erst hinzu, wenn Du hier eine TBitmap zuweist.
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:
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;
Die Implementierung könnte dann so aussehen:
Delphi-Quellcode:
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
Gruß Der Unwissende
[roter Kasten]
Ok, das meiste hier wurde schon gesagt, aber ich poste es mal trotzdem!
[/roter Kasten]