Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
38.563 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Memory Leak bei Interface Delegation

  Alt 27. Okt 2016, 12:16
[F1] auf Delphi-Referenz durchsuchenimplements nennt zuerst die Variante mit dem Interface als Property und danach eine mit der Klasse.

Woebei die Klasse da nichtmal ein Interface ist, laut dem gezeigten Beispiel.
http://docwiki.embarcadero.com/RADSt..._Typ_Interface
Die OH verwendet auch nirgendwo einen Getter, der auf dem Object ein Interface macht, beim Zugrif.

Und nach meinem Verständnis sollte man eigentlich eh niemals Interface-Referenzen mit Objekt-Referenzen auf das selbe Objekt mischen?
(Ausnahme die TComponents, welche nicht referenzgezählt sind, auch wenn das schon ein bissl krank ist, denn das knallt, wenn man ein Free macht, bevor die letzte Interfacereferenz freigegeben wurde)

Beides vom Typ Interface und ich hab diesmal zwei Speicherlecks. (TInterfacedObject statt TAggregatedObject ergab nur ein Speicherleck )
Delphi-Quellcode:
type
  IMyInterface = interface
    procedure Show;
  end;

  TMyClass = class(TAggregatedObject, IMyInterface)
    procedure Show;
  end;

  TMyWrapper = class(TInterfacedObject, IMyInterface)
  private
    FMyInterface: IMyInterface;
  public
    constructor Create;
    property MyInterface: IMyInterface read FMyInterface implements IMyInterface;
  end;

procedure TMyClass.Show;
begin
  ShowMessage('blubb');
end;

constructor TMyWrapper.Create;
begin
  inherited;
  FMyInterface := TMyClass.Create(Self);
end;

procedure TForm4.FormCreate(Sender: TObject);
var
  MyInterface: IMyInterface;
begin
  ReportMemoryLeaksOnShutdown := True;
  MyInterface := TMyWrapper.Create;
  MyInterface.Show;
end;
Mit der Klasse als interface hab ich kein Speicherleck.
Delphi-Quellcode:
type
  IMyInterface = interface
    procedure Show;
  end;

  TMyClass = class(TAggregatedObject, IMyInterface)
    procedure Show;
  end;

  TMyWrapper = class(TInterfacedObject, IMyInterface)
  private
    FMyClass: TMyClass;
  public
    constructor Create;
    destructor Destroy; override;
    property MyInterface: TMyClass read FMyClass implements IMyInterface;
  end;

procedure TMyClass.Show;
begin
  ShowMessage('blubb');
end;

constructor TMyWrapper.Create;
begin
  inherited;
  FMyClass := TMyClass.Create(Self);
end;

destructor TMyWrapper.Destroy;
begin
  FMyClass.Free;
  inherited;
end;

procedure TForm4.FormCreate(Sender: TObject);
var
  MyInterface: IMyInterface;
begin
  ReportMemoryLeaksOnShutdown := True;
  MyInterface := TMyWrapper.Create;
  MyInterface.Show;
end;
Die Klasse als Klasse funktioniert auch.
Delphi-Quellcode:
type
  IMyInterface = interface
    procedure Show;
  end;

  TMyClass = class
    procedure Show;
  end;

  TMyWrapper = class(TInterfacedObject, IMyInterface)
  private
    FMyClass: TMyClass;
  public
    constructor Create;
    destructor Destroy; override;
    property MyInterface: TMyClass read FMyClass implements IMyInterface;
  end;

procedure TMyClass.Show;
begin
  ShowMessage('blubb');
end;

constructor TMyWrapper.Create;
begin
  inherited;
  FMyClass := TMyClass.Create;
end;

destructor TMyWrapper.Destroy;
begin
  FMyClass.Free;
  inherited;
end;

procedure TForm4.FormCreate(Sender: TObject);
var
  MyInterface: IMyInterface;
begin
  ReportMemoryLeaksOnShutdown := True;
  MyInterface := TMyWrapper.Create;
  MyInterface.Show;
end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014

Geändert von himitsu (27. Okt 2016 um 12:21 Uhr)
  Mit Zitat antworten Zitat