Einzelnen Beitrag anzeigen

Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#4

Re: Erzeugen und Freigeben von Objekten und Speicher

  Alt 4. Jun 2007, 11:59
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]
  Mit Zitat antworten Zitat