as you want "have" a obj-reference in your function( var XXXX ):boolean.... you should use function( out XXXX):boolean;
the scope should be the same then "var definition" on caller procedure!!! if "the var is LOCAL (into proceudre) then the life is local", else if the var is "unit-GLOBAL", then, the obj is alive while unit is alive.
unit uMyInterfX;
interface
type
IMyInterfX = interface
['{AE871A32-4B6A-4E4B-B825-92B762493D3F}']
function Hello(AValue: string = ''): string;
function HelloObj(out MyObjOUT: IMyInterfX): boolean;
end;
TMyClassX = class(TInterfacedObject, IMyInterfX)
private
public
function Hello(AValue: string = ''): string;
function HelloObj(out MyObjOUT: IMyInterfX): boolean;
end;
implementation
uses
System.SysUtils;
{ TMyClassX }
function TMyClassX.Hello(AValue: string = ''): string;
begin
result := 'Hello World: ' + AValue + ' ref-Counting: (' + Self.RefCount.ToString + ') ';
end;
function TMyClassX.HelloObj(out MyObjOUT: IMyInterfX): boolean;
begin
result := false;
//
try
MyObjOUT := TMyClassX.Create; // created locally, but will be refereced in "caller Obj"-scope!!
result := true;
except
// ?
end;
end;
end.
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
uMyInterfX;
var
LMyInterfXGLOBALForUnit: IMyInterfX;
LObjGlobal : IMyInterfX;
procedure MyOtherProc(const AObj: IMyInterfX);
begin
if (AObj <> nil) then
ShowMessage(AObj.Hello(' AObj from MyOtherProc'));
end;
procedure TForm1.Button1Click(Sender: TObject);
var
LMyInterfXLOCALForProcedure: IMyInterfX;
LObj : IMyInterfX; // local obj interfaced but will created into "TMyClass interfaced" ... it is gone too!
LObj2 : IMyInterfX;
begin
LMyInterfXLOCALForProcedure := TMyClassX.Create;
// ...try
ShowMessage(LMyInterfXLOCALForProcedure.Hello + ' LMyInterfXLOCALForUnit');
// finally
// ...LMyInterfXLOCALForProcedure.FREE; // does not works in Interfaced object!!!
// ...end;
//
if LMyInterfXLOCALForProcedure.HelloObj(LObj) and (LObj <> nil) then
ShowMessage(LObj.Hello(' from LObj (Local)'));
//
MyOtherProc(LObj);
LObj2 := LObj;
MyOtherProc(LObj);
//
//
LMyInterfXGLOBALForUnit := TMyClassX.Create;
//
ShowMessage(LMyInterfXLOCALForProcedure.Hello + ' LMyInterfXGLOBALForUnit');
//
if LMyInterfXGLOBALForUnit.HelloObj(LObjGlobal) and (LObjGlobal <> nil) then
ShowMessage(LObjGlobal.Hello(' from LObj (Global)'));
//
// summary:
// LMyInterfXLOCALForProcedure is done when this procedure out-of-scope
// LMyInterfXGLOBALForUnit still alive same that this procedure is out-of-scope... until unit is gone!
end;
procedure TForm1.Button2Click(Sender: TObject);
var
LObj2: IMyInterfX;
begin
// ShowMessage(LMyInterfXLOCALForProcedure.Hello + ' LMyInterfXLOCALForUnit'); // not works because it's a LOCAL definition
//
if (LMyInterfXGLOBALForUnit <> nil) then
begin
ShowMessage(LMyInterfXGLOBALForUnit.Hello + ' LMyInterfXGLOBALForUnit is alive');
//
if (LObjGlobal <> nil) then
ShowMessage(LObjGlobal.Hello(' Obj Global its alive '))
else
ShowMessage('Obj Global is nil');
end
else
ShowMessage('LMyInterfXGLOBALForUnit is nil');
//
MyOtherProc(LObjGlobal);
LObj2 := LObjGlobal;
MyOtherProc(LObjGlobal);
end;
initialization
ReportMemoryLeaksOnShutdown := true;
end.