我在该事件中声明了mybutton,并创建了mybutton,在过程结束时,变量mybutton应该被释放了吧?可是被实例的对象依然存在,那我该如何释放对象呢?

  • 主题发起人 于小澜
  • 开始时间

于小澜

Unregistered / Unconfirmed
GUEST, unregistred user!
我在该事件中声明了mybutton,并创建了mybutton,在过程结束时,变量mybutton应该被释放了吧?可是被实例的对象依然存在,那我该如何释放对象呢?(88分)<br />procedure TForm1.Button1Click(Sender: TObject);
var
mybutton : Tbutton;
begin
mybutton := Tbutton.Create(self);
with mybutton do
begin
caption := 'asdf';
parent := Form1;
left := 30;
top := 40;
end;
end;
我在该事件中声明了mybutton,并创建了mybutton,在过程结束
时,变量mybutton应该被释放了吧?可是被实例的对象依然存在
,那我该如何释放对象呢?
请各位指出我概念模糊之处。
 
自己Create 的自己 mybutton.free 啊
 
在何出free?
 
应该在FormCreate时创建,在FormClose时释放。如

type
TForm1 = class(TForm)
...
private
MyButton: TButton;
...
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
MyButton := TButton.Create(Self);
with MyButton do begin
Parent := Self;
...
end;
...
end;

procedure TForm1.FormClose(Sender: TObject);
begin
if Assigned(MyButton) then MyButton.Free;
end;
...
 
代码修改如下!
procedure TForm1.Button1Click(Sender: TObject);
var
mybutton : Tbutton;
begin
mybutton := Tbutton.Create(self);
try
with mybutton do
begin
caption := 'asdf';
parent := Form1;
left := 30;
top := 40;
end;
finally
mybutton.free
end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
mybutton : Tbutton;
begin
mybutton := Tbutton.Create(self);
try
with mybutton do
begin
caption := 'asdf';
parent := Form1;
left := 30;
top := 40;
end;
finally
mybutton.free;
end;
end;
 
请各位指出我所说概念模糊之处。
 
首先记住一点, Delphi中的类变量其实就是一个指针.
你所执行的MyButton := TButton.Create(self);实际上是在堆中申请一块具体内存存放
Create出来的Button, 然后将这块内存的地址赋值给MyButton这个变量.
因此哪怕你申请的是个局部变量, 过程结束后只是将这个局部变量释放掉了
其实就是指针占用的那块内存(32位)而你这个指针所指向的你Create出来的Button具
体存放的内存则没有释放. 因此造成你认为过程结束后button仍然存在的"怪"现象.
 
ccweifen:
你不是吧?我刚刚创建的就让我释放掉?
 
Another_eYes:
我释放了指针,那我create的对象的name的值是什么,我又如何访问这个对象?
 
1.請問ccweifen : 你創建的mybutton能看見嗎?即使創建了,誰能看見?有誰的眼睛有
CPU的速度快?
2.button1的單擊事件後,mybutton局部變量被釋放,但創建的對象仍在,且能看見,不過
它的name為空,訪問這個對象不能用name,方法有設全局變量,如果變量為Tbutton型,則
創建的對象的name為變量的名稱,如果變量設為整數,則create後用
i:=mybutton.ComponentIndex;(i:integer)保存索引,可以用
showmessage(form1.Components.name);顯示name,可以發現,name為空,
但可設置name:form1.components.name:='button_create',此時再用
showmessage(form1.Components.name);會發現消息框為button_create
一般都是用name訪問對象,沒有name比較麻煩,要用API函數,本人現在不懂
 
那么我创建的这个button,在其所在的窗体free时,是否会随之自动free
是否需要我专门释放它呢?
 
mybutton := Tbutton.Create(self);
这里self应为Form1;括号里的东西是 Owner,Owner与Parent的区别是Owner释放,
则其被Ownered的对象释放,Parent释放,则Children看不见。可参看Delphi的帮助。
由此可见,Form1关闭时,如果Form1是主窗口或窗口关闭形为为caFree则其Owner的
对象都释放,当然也包括mybutton。
 
自己创建的对象,自己释放.这是我对这个问题的看法.
对于seesee的说法,1我不太明白,2好象明白.本来我觉得这方面没有问题,
现在好象也有问题了.
 
自己创建的实例,如果自己没有释放则在Owner释放时被释放,如果没有Owner就会在
进程(Process)结束时释放.在上面的程序中Button1Click每执行一次都会创建一个
新的实例,直到Form1被释放,这会占用大量系统资源。
对于你想实现的功能建议把MyButton声明为全局的。
mybutton := Tbutton.Create(self) 一句改为
if Assigned(MyButton) then
MyButton := TButton.Create(Self);
这个实例如果不手工释放的话,将在Form1释放时被释放。

 
记住一规律:
1. TComponent 子类的 Create 方法都带 Owner 参数,一般都用 Self(窗体) 做参数,
该情况下 TComponent.Create(Owner) 的对象,在 Owner 销毁时将自动被 Owner
销毁(你可以看 TComponent 的 Destroy 方法实现源代码)。
2. TObject 继承下来的其他类,你看它们大部分 Create 方法都不带参数,它们也没有
象 TComponent 一样的隶属管理机制。因此这样的类对象你创建后需要手工 Free。
 
babys:
为什么会占用大量系统资源?button的onclick事件我肯定不会让它无休止的执行。
定义全局变量虽然可行,但如果定义全局变量,会加大函数间的偶合度,降低了函数
的通用性。
 
如果你已经明白了,分分吧
如果你还是不明白,问我吧
 
to 龙丹:
他当然明白了,只不过他用了一反问句而已。
 
to 于小澜
占用大量系统资源,是我假定多次执行会出现的结果.
使用全局变量是因为你要在别的函数里访问这个实例,如果别的函数不访问的话,那你就
不用声明成全局变量了,但Create时,就要想办法检查是否创建过了。
 
顶部