在帮助中对Assigned函数的一段描述 Note: Assigned can't detect a dangling pointer--that is, one that isn't nil but no longer points to valid data. 我就是想找到一个方法判断是否为valid data
其實很簡單, 你只要加一句: btnNew.Free; btnNew:=nil; if btnNew <> nil then //或者if Assigned(btnNew) then //下面的代码会产生异常 ShowMessage(btnNew.Caption);如此而以!
原因就是不加一句 btnNew := nil; 有是不能赋值为Nil。 如:打开一个窗体。这个窗体已经存在时,则显示,否则创建。而关闭时是调用Form.Close 具体代码如下: procedure TfrmFirst.Button1Click(Sender: TObject); begin if not Assigned(frmSecond) then begin frmSecond := TfrmSecond(Application); end; frmSecond.Show; end;procedure frmSecond.btnClose(Sender: TObject); begin Self.Close; end;
上面例子举得不太好,改到MDI中! 主窗体有一个菜单,创建一个子窗体。 procedure TfrmMain.Button1Click(Sender: TObject); begin if not Assigned(frmSecond) then begin frmSecond := TfrmSecond(Application); end; frmSecond.Show; end;子窗体的Close事件 procedure TfrmChild.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end; 第一次可以创建子窗体。但关闭后,就不能再创建子窗体了
坚决拥护 prometheusphinx(白日梦) 的方法, 用freeandnil,绝对没有问题,关于procedure FreeAndNil(var Obj);的帮助 Do not pass a value for Obj if it is not an instance of TObject or one of its descendants.从帮助看可以,obj参数必须是一个TObject的子类或实例。
Note: Assigned can't detect a dangling pointer--that is, one that isn't nil but no longer points to valid data.
我就是想找到一个方法判断是否为valid data
其實很簡單, 你只要加一句: btnNew.Free;
btnNew:=nil;
if btnNew <> nil then //或者if Assigned(btnNew) then
//下面的代码会产生异常
ShowMessage(btnNew.Caption);如此而以!
btnNew := nil;
有是不能赋值为Nil。
如:打开一个窗体。这个窗体已经存在时,则显示,否则创建。而关闭时是调用Form.Close
具体代码如下:
procedure TfrmFirst.Button1Click(Sender: TObject);
begin
if not Assigned(frmSecond) then begin
frmSecond := TfrmSecond(Application);
end;
frmSecond.Show;
end;procedure frmSecond.btnClose(Sender: TObject);
begin
Self.Close;
end;
主窗体有一个菜单,创建一个子窗体。
procedure TfrmMain.Button1Click(Sender: TObject);
begin
if not Assigned(frmSecond) then begin
frmSecond := TfrmSecond(Application);
end;
frmSecond.Show;
end;子窗体的Close事件
procedure TfrmChild.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
第一次可以创建子窗体。但关闭后,就不能再创建子窗体了
FreeAndNil(obj)等于obj.Free;obj:=nil;
procedure TfrmChild.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
Self := nil; //加这么一句,就行了呀
end;要么这样:
function ComponentExists(AComponent: TComponent): Boolean;
begin
try
AComponent.HasParent;
result := True;
except
result := False;
end;
end;procedure TForm1.Button1Click(Sender: TObject);
var
Component: TComponent;
begin
Component := TComponent.Create(self);
//Obj.Free;
if ComponentExists(Obj) then
showmessage('component ok')
else
showMessage('component err');
end;关键在于HasParent是TComponent的对象方法,而不是成员方法,所以管用。
procedure TfrmChild.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
Self := nil; //加这么一句,就行了呀
end;要么这样:
function ComponentExists(AComponent: TComponent): Boolean;
begin
try
AComponent.HasParent;
result := True;
except
result := False;
end;
end;procedure TForm1.Button1Click(Sender: TObject);
var
Component: TComponent;
begin
Component := TComponent.Create(self);
//Obj.Free;
if ComponentExists(Obj) then
showmessage('component ok')
else
showMessage('component err');
end;关键在于HasParent是TComponent的对象方法,而不是成员方法,所以管用。
你的第一种解决方案,我试了一下,好象不行。从理论也说不过去。
如果换成frmChild := nil; 倒是可以的。你的第二种方案,我也想到了,采用异常处理(你那个传的参数类型为TObject更通用一点),但速度有点慢(要访问RTII)。
不知是否有更好的方法。多谢Musicwind及各位兄弟。
用freeandnil,绝对没有问题,关于procedure FreeAndNil(var Obj);的帮助
Do not pass a value for Obj if it is not an instance of TObject or one of its descendants.从帮助看可以,obj参数必须是一个TObject的子类或实例。
《探究:Delphi中的对象指针是否可用》
http://www.csdn.net/develop/read_article.asp?id=9508
不用RTTI,好像没有办法。