Vojtech
Vojtech

Reputation: 2603

Is it a object or an interface? Do I need to free it or not?

Good day! Function GetService creates instance of class THTTPRIO and returns it as IInvokable. I use this interface/object in another function. Do I have to free it or not when I don't need it anymore? Interfaces does not need to be freed but I'm confused with the fact that RIO is created as object of THTTPRIO class.

function GetService(Addr: string): IInvokable;
var
  RIO: THTTPRIO;
begin
  RIO := THTTPRIO.Create(nil)
  RIO.URL := Addr;
  Result := (RIO as IInvokable);
end;

Where:

IInvokable = interface(IInterface);
THTTPRIO = class(TComponent, IInterface, IRIOAccess);

Thank you in advance! Vojtech

Upvotes: 5

Views: 1320

Answers (1)

David Heffernan
David Heffernan

Reputation: 612964

To answer the question you need to check how IInterface._AddRef and IInterface._Release are implemented for this class. They look like this:

function TRIO._AddRef: Integer;
begin
  Result := TInterlocked.Increment(FRefCount);
end;

function TRIO._Release: Integer;
begin
  Result := TInterlocked.Decrement(FRefCount);
  if (Result = 0) and not (Owner is TComponent) then
    Destroy;
end;

This means that the lifetime of the object is managed by interface reference counting. Which means that your code is correct and does not leak.

Note that if you had passed an Owner in the constructor then the lifetime would be managed by that owner instead.

Your code is still somewhat liable to leaking if the setting of URL raises. I would write it like this:

function GetService(const Addr: string): IInvokable;
begin
  Result := THTTPRIO.Create(nil);
  (Result as IRIOAccess).RIO.URL := Addr;
end;

Having said all of that, the THTTPRIO class does not support IInvokable so perhaps your actual code looks slightly different.

Upvotes: 6

Related Questions