四个button,2个Edit,哪位给讲解一下,我准备了板凳。unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
Button2: TButton;
Button3: TButton;
Button4: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
Edit2 :=Edit1;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
FreeAndnil(Edit1);
end;procedure TForm1.Button3Click(Sender: TObject);
begin
FreeAndnil(Edit2);
end;procedure TForm1.Button4Click(Sender: TObject);
begin
if Edit1=nil then
showMessage('Edit1=nil');
if Edit2=nil then
showMessage('Edit2=nil');
if (Edit1 is TEdit) then
showMessage('Edit1 is TEdit');
if (Edit2 is TEdit) then
showMessage('Edit2 is TEdit');
end;end.
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
Button2: TButton;
Button3: TButton;
Button4: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
Edit2 :=Edit1;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
FreeAndnil(Edit1);
end;procedure TForm1.Button3Click(Sender: TObject);
begin
FreeAndnil(Edit2);
end;procedure TForm1.Button4Click(Sender: TObject);
begin
if Edit1=nil then
showMessage('Edit1=nil');
if Edit2=nil then
showMessage('Edit2=nil');
if (Edit1 is TEdit) then
showMessage('Edit1 is TEdit');
if (Edit2 is TEdit) then
showMessage('Edit2 is TEdit');
end;end.
1。Edit2 :=Edit1; 以后,请问 Edit2 原来的空间怎么得到释放呢?所以,要点击 Button3 后,才能点击 Button1。
2。点击 Button1、Button2 后,Edit1 的空间已释放,此时再点击 Button3,将造成对 Edit1 的二次释放,产生错误;而点击 Button4 时,虽然显示 Edit2 还是 TEdit,实际上它的空间已不再有效。你可以在最后加一句:Edit2.text := 'test' 来试试:)
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}var
P : Pointer; {首先需要说,此时,作为指针的Edit1、Edit2、P都在全局数据区,各占4个字节(Win32)
而Edit1和Edit2所指向的对象体,在堆区,为了便于描述,假定如下:
Edit1 -----> 堆内存块 AAA
Edit2 -----> 堆内存块 BBB
此时,AAA和BBB已经在Form1.Create时分配,如果不做任何操作就关闭窗体,则由Form1
负责回收AAA和BBB
}procedure TForm1.Button1Click(Sender: TObject);
begin
P := Edit2; {暂时保存一下Edit2这个指针值,因为它指向堆内存中的BBB}
Edit2 :=Edit1; {指针赋值。此时,Edit1和Edit2这两个指针都指向了堆内存中的AAA}
Edit2.Text := 'abc'; {看一下}
end;procedure TForm1.Button2Click(Sender: TObject);
begin
FreeAndnil(Edit1);
{此时,AAA已经被释放,并且Edit1的指针值被赋值为nil}
end;procedure TForm1.Button3Click(Sender: TObject);
begin
{如果执行了FreeAndnil(Edit1);再执行下面这句,必然导致一个错误
因为Edit2也是指向AAA的,而AAA已经释放}
FreeAndnil(Edit2);
{如果只执行Edit2 := nil是可以的}
end;{此时,BBB还没有被释放!幸亏我们用P保存了它的起始地址!}procedure TForm1.Button5Click(Sender: TObject);
begin
FreeAndNil(P);
end;{ 看了前面的,后面的就不用解释了}procedure TForm1.Button4Click(Sender: TObject);
begin
if Edit1=nil then
showMessage('Edit1=nil');
if Edit2=nil then
showMessage('Edit2=nil');
if (Edit1 is TEdit) then
showMessage('Edit1 is TEdit');
if (Edit2 is TEdit) then
showMessage('Edit2 is TEdit');
end;end.
procedure TForm1.Button2Click(Sender: TObject);
begin
FreeAndnil(Edit1);
{此时,AAA已经被释放,并且Edit1的指针值被赋值为nil}
{但是,此时Edit2的值并不是nil,尽管它所指向的AAA已经被释放}
end;procedure TForm1.Button3Click(Sender: TObject);
begin
{如果先执行FreeAndnil(Edit1);再执行下面这句,必然导致一个错误
因为Edit2此时不是nil,但它指向的AAA已经释放
如果先执行FreeAndnil(Edit2);则Edit1和Edit2同时变为nil,
因为:在Edit2 := Edit1的赋值的时候,不仅仅是指针值的赋值,同时Edit2作为了Edit1的“引用”!
因此,先执行下面这句,再执行FreeAndnil(Edit1);就不会出错了}
FreeAndnil(Edit2);
end;
TO:1L,不变态能引起讨论吗?
我觉得EDIT1,EDIT2都是对象的指针(OOP叫实例吧,但本质是指针)而已,指向一个Tedit类型的空间。
procedure TForm1.Button1Click(Sender: TObject);
begin
Edit2 :=Edit1;
end;
后,Edit2指向EDIT1所指向的地址,此时原来EDIT2的地址没有保存,丢失了。
procedure TForm1.Button2Click(Sender: TObject);
begin
FreeAndnil(Edit1);
end;
后,Edit1指向的TEDIT类实例释放,同时EDIT1赋值Nil,EDIT2也是指向了一个不存在的实例,但没有置nil.此时:
procedure TForm1.Button3Click(Sender: TObject);
begin
FreeAndnil(Edit2);
end;
出错。
procedure TForm1.Button4Click(Sender: TObject);
begin
if Edit1=nil then
showMessage('Edit1=nil');
if Edit2=nil then
showMessage('Edit2=nil');
if (Edit1 is TEdit) then
showMessage('Edit1 is TEdit');
if (Edit2 is TEdit) then
showMessage('Edit2 is TEdit');
end;
应该显示消息'Edit1=nil'
'Edit2 is TEdit'因为其没置nil.
而表现在程序窗口上,虽然Edit2指向了其它地址,但是原来所建立的TEDIT类没有释放,所以在主窗口上EDIT2还是存在的。
我理解的不对的地方欢迎指正。
而FreeAndNil(Edit1)只能将Edit1置为nil?Delphi又是怎么实现这个的?
procedure TForm1.Button1Click(Sender: TObject);
var a,b:TEdit;
begin
a :=Edit1;
b :=a;
freeandnil(b);
if a=nil then
showmessage('a is nil');
if b=nil then
showMessage('b is nil');
end;
这个只有b是nil;
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;
应该不是FreeAndNil造成的,应该和RTTI有关。
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end; 测试一下就知道了,测试的结果说明一切。
PRecData = ^TRecData;
TRecData = record
Str : string;
end;var
P:PRecData;
begin
try
new(P);
P.Str := 'aaa'; //以下2句
P^.Str := 'bbb'; //
finally
Dispose(P);
end;
end;
TComponent.SetReference(False)
TComponent.RemoveComponent(...)
TComponent.Destroy
TControl.Destroy
TWinControl.Destroy
TObject.Free
...总结:设计期间创建的元件,即存在窗体资源(.dfm)中的元件,当这类元件被释放的时候,相应的窗体字段也会被赋值为空。
详细过程参考TComponent.SetReference()方法。楼主可以结贴了。