如何判断一个动态创建的控件是否被free掉?(50分)

  • 主题发起人 主题发起人 8341
  • 开始时间 开始时间
8

8341

Unregistered / Unconfirmed
GUEST, unregistred user!
我用动态控件数组,有时free掉其中的某个,在程序结束时,要把所有动态控件释放,但是
有些已经释放了,怎么判断呢?
例如:
label[3].free;

for i:=0 to 10 do
label.free;

如果运行到i=3时,就会出错。我用
try
label.free;
except
end;
第一次可以,但是两次后也不行。如何在label.free前判断它是否存在?




 
for i:=0 to 10 do
begin
if label<>Nil then
label.free;
end;
 
从原理上说, label是一个指针, 因此很难知道她所指向的地方是否是一个创建好的对象,
或者指向的对象是否已经释放了.
合理的方法是:
释放 label对象之后, 在给 label赋Nil.
这样, 您就可以通过判断该指针是否为Nil来指导对象是否创建或清除了.
 
更好的Free方法:
FreeAndNil(Label);
无论Free几次都可以。
 
if assigned(lable) then
 
同意王公子
 
我试了一下
1. label.free;
label:=nil;
2. if label<>Nil then
label.free;
或者
if assigned(lable) then
label.free;
都可以的。
关键是第1步中 label:=nil。

另:
FreeAndNil(Label);我试了一下,报错。
 
也可以不用nil就可以判断是不是己经释放的。
那就是利用它的owner的components数组的。
 
var i:integer;
begin
for i:=0 to self.componentcount-1 do
begin
if self.components is tlabel then
tlabel(self.components).free;
end;
end;
 
同意kelvin-lee和dedema的意见
一个动态创建的控件被free是,首先检查他是否是NIL,
如果不是,那么就Free,但动态创建的控件被free后,
指向该空间的指针.仍然存在,(这时用assigned()是
检查不出来的) 但你再次企图free他时就会出错.
 
判断nil是不行的,因为可能是别的地方的代码释放的。他不会通知这边的代码=nil;
解决这个问题的方法是(TMyComp必须继承自TComponent):
TXXClass.DoSomeProc;
begin
m:=TMyComp.Create;
m.FreeNotification(Self);
end;
然后在TXXClass中覆盖此方法:
//声明:
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
//实现:
procedure TXXClass.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = m) then
m := nil;
end;



 
if assigned(lable) then
label.free;

肯定是不行的,我试过多次都报错。
 
动态控件数组中的各个控件建立时是不是己经指定它们的
Owner为窗体呢?如果是,就不用手工去Free了。
 
只是Free并不会将其完全释放,必须要加上:=nil。
否则用assigned或=nil判断就有可能出错。
 
多人接受答案了。
 
后退
顶部