如何在方法中将外部变量设置为nil?

时间:2013-09-12 08:07:29

标签: delphi reference delphi-7 null tthread

我想继承TThread,以便拥有一个线程类,当FreeOnTerminate = True设置为nil时,它的引用变量。 换句话说,我想做这样的事情:

TFreeAndNilThread = class(TThread)
private
  FReferenceObj: TFreeAndNilThread;  //??  // <-- here I'm holding the reference to myself
protected
  procedure Execute;
  procedure DoTerminate; override;  // <-- here I'll set FReferenceObj to nil after inherited (only if FreeAndNil = True)
public
  constructor Create(CreateSuspended: Boolean; var ReferenceObj); reintroduce;  <-- untyped param like FreeAndNil and TApplication.CreateForm ??
end;

消费者代码应如下所示:

var
  MyThread: TFreeAndNilThread;

begin
  MyThread := TFreeAndNilThread.Create(True, MyThread);
  MyThread.FreeOnTerminate := True;
  MyThread.Resume;
end;

...然后我可以安全地测试Assigned(MyThread)

我看到FreeAndNil如何设置将无类型参数传递给nil的引用对象,但它在本地执行此操作。 在我的情况下,我应该将它“保存”到类字段(FReferenceObj)并在另一个地方(DoTerminate)使其为零。

如何正确传递,存储和检索它? 我可以想到传递和存储MyThread的地址而不是MyThread本身,但我希望有更优雅的方式。

谢谢!

1 个答案:

答案 0 :(得分:1)

您需要存储指向变量的指针。

type
  TFreeAndNilThread = class(TThread)
  private
    FReferenceObj: ^TFreeAndNilThread;
  end;

然后你需要在构造函数中传入引用:

type
  TFreeAndNilThread = class(TThread)
  private
    FReferenceObj: ^TFreeAndNilThread;
  public
    constructor Create(var ReferenceObj: TFreeAndNilThread);
  end;

然后你可以像这样实现它:

constructor TFreeAndNilThread.Create(var ReferenceObj: TFreeAndNilThread);
begin
  inherited Create(True);
  FreeOnTerminate := True;
  FReferenceObj := @ReferenceObj;
end;

当线程死亡时,您将引用设置为nil,如下所示:

ReferenceObj^ := nil;

为方便起见,由于您可能将其视为从中派生其他类的基类,因此您可能更喜欢将构造函数的参数设置为无类型。您可以在不对代码进行其他更改的情况下执行此操作。当你这样做时,构造函数看起来像这样:

constructor Create(var ReferenceObj);

如果设置对nil的引用的代码与尝试引用MyThread的所有其他代码在同一个线程中,那么这只会对您有益。否则你将有竞争条件。

我很确定你的想法不是你问题的解决方案。但是,上面的内容确实向您展示了如何引用变量,这就是您所要求的。