procedure TForm1.Button1Click(Sender: TObject); begin form2.show(); end;procedure TForm1.Button2Click(Sender: TObject); begin Form2.Free;end;procedure TForm1.Button3Click(Sender: TObject); begin if Form2 = nil then showmessage('nil') else showmessage('不为nil'); end;依次点BUTTON1,BUTTON2,BUTTON3,弹出的也是showmessage('不为nil'); 应该是释放了内存,但地址并未置为nil。没深究FreeOnTerminate这个,不对莫怪
不会自己变成nil的,即使不可用
bb存的是aa的地址 这就好像长安街11号有栋楼,楼拆了,长安街11号还在,懂了咩?
应该是释放了内存,但地址并未置为nil。我只是举了个例子
需要么? bb:=nil 自己赋值
VCL 线程函数, ThreadProc 是标准的线程函数 function ThreadProc(Thread: TThread): Integer; var FreeThread: Boolean; begin {$IFDEF LINUX} if Thread.FSuspended then sem_wait(Thread.FCreateSuspendedSem); {$ENDIF} try if not Thread.Terminated then try Thread.Execute; // 调用派生类的Execute函数 except Thread.FFatalException := AcquireExceptionObject; end; finally FreeThread := Thread.FFreeOnTerminate; // 获取是否设置 FreeOnTerminate Result := Thread.FReturnValue; Thread.DoTerminate; Thread.FFinished := True; SignalSyncEvent; if FreeThread then Thread.Free; // 如果FreeOnTerminate = true, 再调用派生类的析构函数,这里是不会设置为nil {$IFDEF MSWINDOWS} EndThread(Result); {$ENDIF} end; 如果要设置为nil, FreeAndNil.
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type ta = class(TThread) instance: PDWORD; procedure Execute; override; destructor Destroy; override; end; TForm1 = class(TForm) Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } a: Ta; public { Public declarations } end;var Form1: TForm1;implementation{$R *.dfm}{ ta }procedure ta.Execute; begin inherited; FreeOnTerminate := True; end;destructor ta.Destroy; var p: PDWORD; begin p := instance; inherited; p^ := 0//置线程实例变量为nil end;procedure TForm1.FormCreate(Sender: TObject); begin a := Ta.Create(True); a.instance := @a;//保存线程实例变量的地址 a.Resume; end;procedure TForm1.Button1Click(Sender: TObject); begin if a = nil then ShowMessage(''); end;end.
用GetExitCodeThread取得线程运行状态,下面Result值表示为: 1:正在运行 2:已终止但未释放,可以用GetLastError获取错误代码 3:已释放 4:不存在/未创建function CheckThr(Thr: TThread): Word; var i:Word; bo:Boolean; begin if Assigned(Thr) then begin bo := GetExitCodeThread(Thr.Handle, i); if bo then begin if i = STILL_ACTIVE then Result:=1 else Result:=2; end else Result:=3; end else Result:=4; end;
begin
form2.show();
end;procedure TForm1.Button2Click(Sender: TObject);
begin
Form2.Free;end;procedure TForm1.Button3Click(Sender: TObject);
begin
if Form2 = nil then showmessage('nil')
else showmessage('不为nil');
end;依次点BUTTON1,BUTTON2,BUTTON3,弹出的也是showmessage('不为nil');
应该是释放了内存,但地址并未置为nil。没深究FreeOnTerminate这个,不对莫怪
这就好像长安街11号有栋楼,楼拆了,长安街11号还在,懂了咩?
bb:=nil 自己赋值
VCL 线程函数, ThreadProc 是标准的线程函数
function ThreadProc(Thread: TThread): Integer;
var
FreeThread: Boolean;
begin
{$IFDEF LINUX}
if Thread.FSuspended then sem_wait(Thread.FCreateSuspendedSem);
{$ENDIF}
try
if not Thread.Terminated then
try
Thread.Execute; // 调用派生类的Execute函数
except
Thread.FFatalException := AcquireExceptionObject;
end;
finally
FreeThread := Thread.FFreeOnTerminate; // 获取是否设置 FreeOnTerminate
Result := Thread.FReturnValue;
Thread.DoTerminate;
Thread.FFinished := True;
SignalSyncEvent;
if FreeThread then Thread.Free; // 如果FreeOnTerminate = true, 再调用派生类的析构函数,这里是不会设置为nil
{$IFDEF MSWINDOWS}
EndThread(Result);
{$ENDIF}
end;
如果要设置为nil, FreeAndNil.
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
ta = class(TThread)
instance: PDWORD;
procedure Execute; override;
destructor Destroy; override;
end; TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
a: Ta;
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}{ ta }procedure ta.Execute;
begin
inherited;
FreeOnTerminate := True;
end;destructor ta.Destroy;
var
p: PDWORD;
begin
p := instance;
inherited;
p^ := 0//置线程实例变量为nil
end;procedure TForm1.FormCreate(Sender: TObject);
begin
a := Ta.Create(True);
a.instance := @a;//保存线程实例变量的地址
a.Resume;
end;procedure TForm1.Button1Click(Sender: TObject);
begin
if a = nil then ShowMessage('');
end;end.
这样是不行的,因为Thread也只是一个变量而已,你把Thread置为nil,不会影响变量bb的值!比如v1,v2都为1,你把v1置为0,v2还是1!!!
1:正在运行
2:已终止但未释放,可以用GetLastError获取错误代码
3:已释放
4:不存在/未创建function CheckThr(Thr: TThread): Word;
var
i:Word;
bo:Boolean;
begin
if Assigned(Thr) then
begin
bo := GetExitCodeThread(Thr.Handle, i);
if bo then
begin
if i = STILL_ACTIVE then
Result:=1
else
Result:=2;
end else
Result:=3;
end else
Result:=4;
end;