Spring4D - Is it not possible to use Weak<Shared<TObject>>?

182 Views Asked by At

I want to create a connection provider which issues Shared<T> and holds on to a Weak<T> but even though only 1 T instance gets created there are 2 attempts to destroy.

I have included a basic example below.

  TMyObj = class
  private
    class var
      fNextId: Integer;
    var
      fId: Integer;
  public
    constructor Create;
    destructor Destroy; override;
  end;

  IProv = interface
  ['{0497DFE9-A77C-4250-82AF-FDA3823A91EC}']
    function Get: Shared<TMyObj>;
    function GetNew: Shared<TMyObj>;
  end;

  TProv = class(TInterfacedObject, IProv)
  private
    fInstance: Weak<TMyObj>;
  protected
    function Get: Shared<TMyObj>;
    function GetNew: Shared<TMyObj>;
  end;

  THolder = class
  private
    fO: Shared<TMyObj>;
  public
    constructor Create(O: Shared<TMyObj>);
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  var P:=TProv.Create as IProv;

  var H:=THolder.Create(P.Get);
  var H2:=THolder.Create(P.Get);
  FreeAndNil(H);
  FreeAndNil(H2);
  OutputDebugString('End');
end;

{ TMyObj }

constructor TMyObj.Create;
begin
  fId:=InterlockedIncrement(fNextId);
  OutputDebugString(PChar(fId.ToString+' Creating On '+GetCurrentThreadId.ToString));
end;

destructor TMyObj.Destroy;
begin
  OutputDebugString(PChar(fId.ToString+' Destroying On '+GetCurrentThreadId.ToString));
  inherited;
end;

{ TProv }

function TProv.Get: Shared<TMyObj>;
begin
  if fInstance.IsAlive then
    Exit(fInstance.Target);

  Result:=GetNew;
  fInstance:=Result;
end;

function TProv.GetNew: Shared<TMyObj>;
begin
  Result:=TMyObj.Create;
end;

{ THolder }

constructor THolder.Create(O: Shared<TMyObj>);
begin
  fO:=O;
end;

I then thought that Weak<T> would only work for interfaces so changed the implementation to hold a Weak<IShared<T>> but then false is returned when I call Weak.IsAlive.

0

There are 0 best solutions below