我想继承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本身,但我希望有更优雅的方式。
谢谢!
答案 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
的所有其他代码在同一个线程中,那么这只会对您有益。否则你将有竞争条件。
我很确定你的想法不是你问题的解决方案。但是,上面的内容确实向您展示了如何引用变量,这就是您所要求的。