AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Räumt diese Komponente hinter sich auf?

Ein Thema von hzzm · begonnen am 3. Aug 2018 · letzter Beitrag vom 14. Aug 2018
Antwort Antwort
Seite 1 von 2  1 2      
hzzm

Registriert seit: 8. Apr 2016
103 Beiträge
 
Delphi 10 Seattle Professional
 
#1

Räumt diese Komponente hinter sich auf?

  Alt 3. Aug 2018, 06:06
Delphi-Version: 10 Seattle
Guten Morgen,

räumt diese Komponente hinter sich auf (sind die Destruktoren korrekt)?

Delphi-Quellcode:
unit ImageMultiStates;

    interface

    uses
      Vcl.Graphics, Vcl.StdCtrls, System.SysUtils, System.Classes, Vcl.Controls, Vcl.ExtCtrls, Forms, Generics.Collections;

    type

      TPic = class(TCollectionItem)
      private
        FPicture: TPicture;
        procedure SetPicture(const value: TPicture);
      protected
        function GetDisplayName: String; override;
      public
        procedure Assign(Source: TPersistent); override;
        constructor Create(Collection: TCollection); override;
      published
        property Picture: TPicture read FPicture write SetPicture;
      end;

      TPictures = class(TOwnedCollection)
      private
        function GetPic(Index: Integer): TPic;
        procedure SetPic(Index: Integer; Value: TPic);
      public
        constructor Create(AOwner: TComponent);
        destructor Destroy;
        property Picture[Index: Integer]: TPic read GetPic write SetPic;
      end;

      TImageMultiStates = class(TImage)
      private
        FPictures: TPictures;
        FOnMouseDownPic: Integer;
        FOnMouseUpPic: Integer;
        procedure SetPictures(const Value: TPictures);
      public
        ActivePic: Integer;
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
        procedure ActivatePic(Index: Integer);
        procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
        procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
      published
        property Pictures: TPictures read FPictures write SetPictures;
        property OnMouseDownPic: Integer read FOnMouseDownPic write FOnMouseDownPic;
        property OnMouseUpPic: Integer read FOnMouseUpPic write FOnMouseUpPic;
      end;

    procedure Register;

    implementation

    constructor TPic.Create(Collection: TCollection);
    begin
      inherited;
      FPicture := TPicture.Create;
    end;

    procedure TPic.Assign(Source: TPersistent);
    begin
      if Source is TPic then
        FPicture := TPic(Source).FPicture
      else
        inherited;
    end;

    procedure TPic.SetPicture(const Value: TPicture);
    begin
      FPicture.Assign(Value);
      if Index=0 then
        TImageMultiStates(TPictures(GetOwner).GetOwner).Picture.Assign(Value);
    end;

    function TPic.GetDisplayName;
    begin
      Result := Format('Picture %d',[Index]);
    end;


    constructor TPictures.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner, TPic);
    end;

    destructor TPictures.Destroy;
    begin
      inherited Destroy;
    end;

    procedure TPictures.SetPic(Index: Integer; Value: TPic);
    begin
      inherited SetItem(Index, Value);
    end;

    function TPictures.GetPic(Index: Integer): TPic;
    begin
      Result := inherited GetItem(Index) as TPic;
    end;


    constructor TImageMultiStates.Create(AOwner: TComponent);
    begin
      inherited;
      FOnMouseDownPic := -1;
      FOnMouseUpPic := -1;
      FPictures := TPictures.Create(AOwner);
    end;

    destructor TImageMultiStates.Destroy;
    begin
      FPictures.Free;
      inherited;
    end;

    procedure TImageMultiStates.SetPictures(const Value: TPictures);
    begin
      FPictures.Assign(Value);
    end;

    procedure TImageMultiStates.ActivatePic(Index: Integer);
    begin
      if (Index < FPictures.Count) and (Index >= 0) then
      begin
        ActivePic := Index;
        Picture.Assign(TPic(FPictures.Items[Index]).FPicture);
      end
      else
      begin
        ActivePic := -1;
        Picture.Assign(nil);
      end;
    end;

    procedure TImageMultiStates.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    begin
      if FOnMouseDownPic<>-1 then
        Picture.Assign(TPic(FPictures.Items[FOnMouseDownPic]).FPicture);
      inherited;
    end;

    procedure TImageMultiStates.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    begin
      if FOnMouseUpPic<>-1 then
        Picture.Assign(TPic(FPictures.Items[FOnMouseUpPic]).FPicture);
      inherited;
    end;

    procedure Register;
    begin
      RegisterComponents('Standard', [TImageMultiStates]);
    end;

    end.
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.920 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Räumt diese Komponente hinter sich auf?

  Alt 3. Aug 2018, 06:16
Ein wichtiges Werkzeug in solchen Fragen: Delphi kann Dir das selbst sagen.
Wenn Du im Projektquellcode die Anweisung „ReportMemoryLeaksOnShutdown:=true;“ setzt, bekommst Du einen Hinweis, wenn am Ende etwas nicht artig aufgeräumt wird.
Die dahinterstehende Buchhaltung kostet Rechenzeit, o.g. Anweisung sollte also nur zum Testen in Deinem Projekt stehen.
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.156 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Räumt diese Komponente hinter sich auf?

  Alt 3. Aug 2018, 06:32
Und dann spiele doch mal etwas mit deiner eigenen Komponente wenn ReportMemoryLeaksOnShutdown = true ist. Oder noch besser: Schreibe vernünftige Unit-Tests. Zum Beispiel für TPic.Assign(..) . Da wirst du zum Beispiel feststellen dass das was du im Konstruktor in FPicture reingesteckt hast niemals freigegeben wird.


PS: "Richtig aufräumen" beinhaltet mehr als nur Speicher der Delphi-Objekte freigeben. Wenn deine Klasse beispielsweise mit Dateien hantiert und ein Handle nicht mehr freigibt, eine Netzwerkverbindung nicht schließt, … All sowas.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.580 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Räumt diese Komponente hinter sich auf?

  Alt 3. Aug 2018, 10:19
So wie du es aktuell hast, ist die korrekte Speicherverwaltung sehr schwer. Denn im Assign kopierst du z.B. nur den Pointer auf ein fremdes Objekt. Dadurch darf dieses Objekt außen gar nicht freigegeben werden, aber auch das Objekt, das den Pointer bekommen hat, kann es nicht tun, da es ja nicht weiß was außen mit dem Objekt passiert.

Delphi selbst macht das so (in TPicture z.B.), dass schlicht im Setter und in Assign der Inhalt kopiert wird. Dadurch sind die einzelnen Objekte voneinander unabhängig und können im Destruktor alles problemlos freigeben, das sie selbst erzeugt haben.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Pfaffe

Registriert seit: 29. Jan 2009
297 Beiträge
 
Delphi 12 Athens
 
#5

AW: Räumt diese Komponente hinter sich auf?

  Alt 3. Aug 2018, 17:57
In meinen Projektdateien steht immer:
{$IFDEF DEBUG}
ReportMemoryLeaksOnShutdown:= True;
{$ENDIF}
  Mit Zitat antworten Zitat
MicMic

Registriert seit: 26. Mai 2018
296 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#6

AW: Räumt diese Komponente hinter sich auf?

  Alt 4. Aug 2018, 07:34
Wie ist es denn eigentlich zu bewerten bzw. was passiert, wenn hier und da ein Speicher nicht freigegeben wird? Es wird dann ja wohl meistens um kleine Sachen gehen.
Ein Betriebssystem wird doch damit bestimmt auch umgehen können. Ich könnte mir vorstellen, dann ist halt irgendwo noch was im Speicher und Windows ist's schnuppe. Schaut natürlich bestimmt wieder anders aus, wenn der Rechner 24h an ist.

Michael
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.387 Beiträge
 
Delphi 12 Athens
 
#7

AW: Räumt diese Komponente hinter sich auf?

  Alt 4. Aug 2018, 07:39
Moin...
Wenn der Prozess (Anwendung) beendet wird, dann räumt Windows den gesamten Speicher des Prozesses auf. Aber es soll auch Anwendungen geben die 365/24 laufen... Für die wäre es fatal wenn irgend eine procedure nicht aufräumt sondern den Speicher zumüllt.
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Räumt diese Komponente hinter sich auf?

  Alt 4. Aug 2018, 08:55
Windows stehen auch nur eine bestimmte Anzahl an Handles zur Verfügung, also kann es da irgendwann auch knapp werden.
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
1.442 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Räumt diese Komponente hinter sich auf?

  Alt 6. Aug 2018, 16:33
Aber es soll auch Anwendungen geben die 365/24 laufen...
Kann gar nicht mehr sein. Irgendwann kommt Windows 10 und macht selbständig einen Neustart
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.156 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

AW: Räumt diese Komponente hinter sich auf?

  Alt 7. Aug 2018, 10:12
Wenn du Windows für Heimversionen einsetzt, dann ja.
Es ist eher dass die Anlagen das können sollten, früher oder später fällt beim Kunden eh der Strom aus
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:52 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