Delphi:声明变量避免循环引用

Fla*_*vio 1 delphi circular-reference

我有一个Delphi单元需要保留各种形式的应用程序的指针,以便稍后对它们进行操作.

为了执行这些操作,我需要将指针强制转换为表单类型,例如.

var    
  ptrFrmMain: Pointer;
  CurrentFrmMain: TfrmMain;
begin
    CurrentFrmMain := ptrFrmMain;
    CurrentFrmMain.Close();
end;
Run Code Online (Sandbox Code Playgroud)

问题是该单元包含在应用程序的所有其他Delphi单元的使用中.因此,虽然我可以Pointer在接口部分声明一个简单类型,但我不能声明在其他单元(例如TfrmMain单元frmMain.pas)中声明的类型.

我可以通过在实现部分中使用来解决这个问题,例如:

interface
type TMyThread = class(TThread)
  Public
    ptrFrmMain:Pointer
...

implementation
    uses frmMain

    var
      CurrentFrmMain: TfrmMain;
Run Code Online (Sandbox Code Playgroud)

但是仍然存在一个问题:我需要将变量特定于我的类实例,用于多线程目的,而不是通用的全局变量.但我不能把它放在我的TmyThread班级里面,因为TfrmMain没有在那里声明,我不能把它放在接口部分的使用中.

一个解决方案是CurrentFrmMain在所有使用它的过程中作为局部变量放置,然后CurrentFrmMain := ptrFrmMain每次都进行转换,但是你知道更好的解决方案吗?

非常感谢你提前.

Rem*_*eau 6

我根本不会在线程中放置一个Form指针.我会让线程保持回调函数,甚至是接口:

type
  TCloseProc: procedure of object;

  TMyThread = class(TThread)
  public
    CloseProc: TCloseProc;
    ...
  end;

...

begin
  if Assigned(CloseProc) then CloseProc();
end;
Run Code Online (Sandbox Code Playgroud)

type
  IMyIntf = interface(IInterface)
  ['{9CC7DB9E-D47F-4B7D-BBF9-6E9B80823086}']
    procedure DoClose;
  end;

  TMyThread = class(TThread)
  public
    Intf: IMyIntf;
    ...
  end;

...

begin
  if Assigned(Intf) then Intf.DoClose();
end;

...

type
  TfrmMain = class(TForm, IMyIntf)
  public
    procedure doClose;
  end;

procedure TfrmMain.doClose;
begin
  Close;
end;
Run Code Online (Sandbox Code Playgroud)

创建线程时,将Form方法分配给那些回调,或者将Form的接口实现传递给线程:

Thread := TMyThread.Create(True);
Thread.CloseProc := frmMain.Close;
Thread.Resume;
Run Code Online (Sandbox Code Playgroud)

Thread := TMyThread.Create(True);
Thread.Intf := frmMain as IMyIntf;
Thread.Resume;
Run Code Online (Sandbox Code Playgroud)

无论哪种方式,线程根本不需要知道实际的表单,同时仍然满足特定于表单的功能.

  • @Arioch'The:ARC在VCL中不是问题,至少因为`TComponent`禁用组件对象实现的接口的引用计数,而``TForm`是`TComponent`后代.而`as`运算符为接口实现提供了必要的检查. (3认同)