unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TA = class
private
Fs: string;
public
constructor Create(s: string);
destructor Destroy;override;
procedure test;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
A: TA;
begin
A := TA.Create('test');
A.Free;
//A := nil;
//if A <> nil then
if Assigned(A) then
A.test;
end;{ TA }constructor TA.Create(s: string);
begin
Fs:= s;
end;destructor TA.Destroy;
begin
Fs:= '';
inherited;
end;procedure TA.test;
begin
ShowMessage(Fs);
end;end.
例如以上代码,A对象所指向的堆内存已经free了,但无论判断A是否为nil或者用assigned判断,都可以调用A.test而不出错。应该怎么判断A已经Free而不至于执行A.test呢?
不然貌似delphi里面还真的不能判断.
//if A <> nil then正确的做法就应该是这样啊,为什么要注释掉.Free以后立即赋值为nil,为以后使用前判断提供依据.
var
A: TA;
begin
A := TA.Create('test');
FreeAndNil(A); {和A.Free; A:=nil;是一个效果}
if Assigned(A) then
A.test; {这句将不会被执行了}
end;
或者说说你遇到了什么样的情况非要这样判断,而不能在free后赋值nil(因为这才是推荐的编码方法).
引用 7 楼 JPEXE 的回复:
我的目的就是想在A不为nil的情况下如何判断堆内存是否已释放
/Quote]A不为NIL的时候还有可能被释放了吗?
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
{ 用这个类实现标记/判断对象是否已被释放 }
TCheckIsAlive = class
private
flag: Boolean; { 类创建时成员变量 flag 一定会被初始化为 False }
function GetIsAlive: Boolean;
public
destructor Destroy; override;
property IsAlive: Boolean read GetIsAlive;
end; TA = class(TCheckIsAlive) { 注意继承 }
private
Fs: string;
public
constructor Create(s: string);
destructor Destroy; override;
procedure test;
end; TForm1 = class(TForm)
btn1: TButton;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);
var
A: TA;
begin
A := TA.Create('test');
A.Free; { 检查是否 alive }
if A.IsAlive then
A.test;
end;{ TA }constructor TA.Create(s: string);
begin
Fs := s;
end;destructor TA.Destroy;
begin
Fs := '';
inherited;
end;procedure TA.test;
begin
ShowMessage(Fs);
end;{ TCheckIsFree }destructor TCheckIsAlive.Destroy;
begin
flag := True; { 修改标记 }
end;function TCheckIsAlive.GetIsAlive: Boolean;
begin
Result := not flag;
end;end.
不需改变对TA类的使用,只需让TA从TCheckIsAlive继承就行了.
{ TCheckIsFree } 应该是 { TCheckIsAlive }
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
{ 用这个类实现标记/判断对象是否已被释放 }
TCheckIsAlive = class
private
flag: Boolean; { 类创建时成员变量 flag 一定会被初始化为 False }
function GetIsAlive: Boolean;
public
destructor Destroy; override;
property IsAlive: Boolean read GetIsAlive;
end; TA = class(TCheckIsAlive) { 注意继承 }
private
Fs: string;
public
constructor Create(s: string);
destructor Destroy; override;
procedure test;
end; TForm1 = class(TForm)
btn1: TButton;
btn2: TButton;
procedure btn1Click(Sender: TObject);
procedure btn2Click(Sender: TObject);
private
FA: TA;
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.btn1Click(Sender: TObject);
var
A: TA;
begin
A := TA.Create('test'); { 创建 }
FA := A; { 引用 } { 检查是否 alive }
if A.IsAlive then
A.test; { 未释放->会执行 } A.Free; { 释放 }
end;procedure TForm1.btn2Click(Sender: TObject);
begin
{ 检查是否 alive }
if FA.IsAlive then
FA.test; { 已被释放->不会执行 }
end;{ TA }constructor TA.Create(s: string);
begin
Fs := s;
end;destructor TA.Destroy;
begin
Fs := '';
inherited;
end;procedure TA.test;
begin
ShowMessage(Fs);
end;{ TCheckIsAlive }destructor TCheckIsAlive.Destroy;
begin
flag := True; { 修改标记 }
end;function TCheckIsAlive.GetIsAlive: Boolean;
begin
Result := not flag;
end;end.
这样实现是不行的。
你只是在特定的类中做标记,我是想问在普通的类应用中有没可能做判断
begin
a:=TA.Create;
A.i:=100;
ShowMessage(IntToStr(a.InstanceSize));
a.Free;
ShowMessage(IntToStr(a.InstanceSize));
end;
i:integer;
end;
所以无论a释放与否,结果都是一样。
因此java和.net才要在虚拟机上搞内存回收