Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   ARC-sichere Zuweisung von self an Interface-Variable (https://www.delphipraxis.net/192834-arc-sichere-zuweisung-von-self-interface-variable.html)

dpg123 23. Mai 2017 16:54

ARC-sichere Zuweisung von self an Interface-Variable
 
Liebes Forum,

ich möchte die self-Referenz einer Interface-Variable zuordnen, ohne das automatic reference counting durcheinander zu bringen, bisher ohne Erfolg.

Hier der Code (Sinnhaftigkeit ist erstmal egal):

Delphi-Quellcode:
type

  IRequest = interface(IInterface)
  ['{AA14B3B9-9874-4E25-80BC-3C5A9A301ABC}']

    function get(): Extended;

  end;


  TRequest = class(TInterfacedObject, IRequest)

    strict private

      var

        requestValue: IRequest;

    public

      function get(): Extended;

      constructor create();

  end;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TRequest }

constructor TRequest.create;
begin

  inherited create();

// bei allen 3 Varianten gibts nen Memory Leak

  self.requestValue := Self;

//  self.requestValue := Self as IRequest;

//  self.requestValue := IRequest(self);

end;

function TRequest.get: Extended;
begin
  result := 0;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  lReq: IRequest;

begin

  lReq := TRequest.create;

end;

Fritzew 23. Mai 2017 17:00

AW: ARC-sichere Zuweisung von self an Interface-Variable
 
Sinn oder Unsinn mal dahingestellt, in dem Moment an dem Du einer internen Interface Variable self zuweist, wird der Referenz count dieser Variable erhöht. Wenn Du also von aussen per interface auf diese klasse zugreifst hat die mindestens einen referenzcount von 2. Du musst also um dieses Objekt freizugeben irgendeine Möglichkeit einbauen den Refernzcount wieder zu verringern.
Aber ohne den "Sinn" dieser Aktion zu kennen sehe ich keinen "Sinn" darin, darauf tiefer einzugehen. Das Konstrukt in deinem Ausgangsposting mach halt keinen .........

bra 23. Mai 2017 17:06

AW: ARC-sichere Zuweisung von self an Interface-Variable
 
Vielleicht bringt es etwas, wenn du requestValue als weak kennzeichnest?

Delphi-Quellcode:
      var
        [weak] requestValue: IRequest;
Ob das Sinn macht, sei mal dahingestellt ;)

Fritzew 23. Mai 2017 17:10

AW: ARC-sichere Zuweisung von self an Interface-Variable
 
Zitat:

Vielleicht bringt es etwas, wenn du requestValue als weak kennzeichnest?
Da wir nicht wissen welcher Delphi Version der TE einsetzt können wir eh nur raten....

dpg123 23. Mai 2017 17:17

AW: ARC-sichere Zuweisung von self an Interface-Variable
 
Erstmal vielen Dank für eure Beiträge!

Es scheint wirklich an der Deklaration von requestValue: IRequest in TRequest zu liegen. Deklariere ich sie in einer anderen Klasse geht es (Code siehe unten).

Ja, Sinn macht das so nicht. Hatte ich nur als Minimalbsp gewählt. Ich poste gleich mal die ausführlichere Version, dann wird es entweder klarer, oder ihr findet ne elegantere andere Lösung ;)

[weak] kann ich nicht benutzen, da ich Turbo Delphi verwende (hab ich jetzt auch in mein Profil mal eingetragen...).

Delphi-Quellcode:
type

  IRequest = interface(IInterface)
  ['{AA14B3B9-9874-4E25-80BC-3C5A9A301ABC}']

    function get(): Extended;

  end;

  TRequestController = class(TObject)

    var

      requestValue: IRequest;

  end;


  TRequest = class(TInterfacedObject, IRequest)

    public

      function get(): Extended;

      constructor create( aRequestController: TRequestController );

  end;


  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TRequest }

constructor TRequest.create(  aRequestController: TRequestController );
begin

  inherited create();

  aRequestController.requestValue := Self;

end;

function TRequest.get: Extended;
begin
  result := 0;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  lReq: IRequest;
  lReqCon: TRequestController;
 
begin

  lReqCon := TRequestController.Create();

  lReq := TRequest.create(lReqCon);

  lReqCon.Free;

end;

Fritzew 23. Mai 2017 17:31

AW: ARC-sichere Zuweisung von self an Interface-Variable
 
Das letzte Beispiel sollte eigentlich ohne memoryleak funktionieren, oder?
Wenn Da doch eines ist, (Turbo Delphi ist zu lange her) erzeuge einen Destructor in
TRequestController der die referenz explicit auf Nil setzte also etwa:


Delphi-Quellcode:
TRequestController.Destroy;
begin
 requestValue := nil;
  inherited;
end;

dpg123 23. Mai 2017 17:34

AW: ARC-sichere Zuweisung von self an Interface-Variable
 
Zitat:

Zitat von Fritzew (Beitrag 1372550)
Das letzte Beispiel sollte eigentlich ohne memoryleak funktionieren, oder?
Wenn Da doch eines ist, (Turbo Delphi ist zu lange her) erzeuge einen Destructor in
TRequestController der die referenz explicit auf Nil setzte also etwa:


Delphi-Quellcode:
TRequestController.Destroy;
begin
 requestValue := nil;
  inherited;
end;

ja, kein Leak!

Fritzew 23. Mai 2017 17:36

AW: ARC-sichere Zuweisung von self an Interface-Variable
 
Dann ist ja alles gut.... (Hoffe ich)

himitsu 23. Mai 2017 18:04

AW: ARC-sichere Zuweisung von self an Interface-Variable
 
Turbo Delphi und ARC passt aber nicht so richtig zusammen?
Und da du damit eh nur Windows-Programme erstellen kannst, ist es dem auch egal, daßß er es nicht versteht.

Das ihm "unbekannte" Attribut
Delphi-Quellcode:
[Weak]
sollt er sehen und dann stillschweigend ignorieren.
Und wenn er es nicht macht, dann definiert man eben ein WeakAttribute, für solch alte Delphis.


In Bezug auf ganz neue Delphis kommt da aber noch was hinzu, denn inzwischen wird [Weak] endlich auch im Non-ARC-Umfeld beachtet, also vorallem natürlich für Interfaces.

Fritzew 23. Mai 2017 18:07

AW: ARC-sichere Zuweisung von self an Interface-Variable
 
Blöde Frage könnte das überhaupt schon mit Attributen umgehen? Ich glaube eher an einen Compilierfehler.Aber ist zu lange her.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:49 Uhr.
Seite 1 von 2  1 2      

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