(100分)如何实现组件的自销毁???(100分)

  • 主题发起人 主题发起人 littlestone08
  • 开始时间 开始时间
L

littlestone08

Unregistered / Unconfirmed
GUEST, unregistred user!
如题:
如何在组件自己的代码中检查,如果符合一定的条件,就销毁自己,如果不符合,就继续下面的程序段??
=====
难的地方在于:如果真的是销毁了,可是代码却还是停留在已经FREE的对象的代码中,虽然
可能不会出现异常,但我感觉已经很危险了.
大家有什么思路??就像把TForm的onClose 中的Action设置成好可以释放那个窗体一???

注:我认为用TForm中的那个路不通,因为,Close是调用Windows API的代码,且Realse那个Form时,那一定会是TForm的最后一个操作,所以肯定不会出错.而我想实现的却一定不会是最后的操作
=====
不知道说清楚了没有,请大家给个思路[?]
 
这就像要求一个人不仅要会自杀,还要在自杀后处理自己的后事。
 
不要这样说,FromClose就可以处理自己的自杀,这也不是不可能吧??
有思路给个思路,不要打击我啊.....我是很脆弱的[:D]
 
用FreeAndNil 试试看呢,不仅可以关闭还可以释放其资源
 
建议楼主看看李维的《Inside VCL》
 
来自:tyj06102000, 时间:2006-7-29 14:05:34, ID:3519982
用FreeAndNil 试试看呢,不仅可以关闭还可以释放其资源
=======
现在就是这样做的,而且用了静态异常,免得万一出错了有不好的提示,一般是不会有错的
但是,我觉得这样很不安全啊,因为FreeAndNil后,代码还是在继续执行,而对象却不存在了
--------------------------------------------------------------------
来自:北丐洪七, 时间:2006-7-29 14:05:48, ID:3519983
建议楼主看看李维的《Inside VCL》
INSIDE VCL我正在看,已经看了一半,在看接口部分,但是我在记忆中的VCL部分并不能发现解决此问题 的相关资料
 
用一个程序恐难办到吧,用另一个程序随同主程序一起运行,像那些病毒一样。
 
看看Delphi的内存管理器。
 
你可以参考TPrinter组件的做法;
Printer.FreePrinters;中使用的就是FreeAndNil(FPrinters);
Printer.Refresh中也是调用FreePrinters方法;
当再次调用Printer时,又会自动创建FPrinters对象

当然这种情况适于整个程序统一调用一个对象实例
 
这样吧,看这段代码怎么改才符合逻辑:
Procedure TSaimple.Test;
begin
LoadNumA;
LoadNumB;
if NumA = NumB then
begin
FreeAndNil(Self);
Abort;
end;
if NumA > NumB then
ProcessNum(NumA);
end;
==============
差不多就是这样了,不要问我实现什么功能,实际上,上面的代码的功能在实际中是完全可以用合理的流程来写的,我这样写,是让大家更清楚,我要让这个构件可以自己销毁自己,并终止.但是,如何做呢??这样做全理吗??
在我实际的程序中,差不多就是这样用的,工作起来看起来也正常.请大家讨论一下.
==========
注意,不要去掉自己锁毁的功能
 
你的意思,不过就是在对象自我销毁的同时,能安全处理自己的后事,可以利用对象的析构函数Destroy,很简单也很安全.
一个简单例子:
TSimple = class
private
bSelfDestroy: Boolean;
procedure Test;
public
constructor Create;
destructor Destroy;
end;

constructor TSimple.Create;
begin
bSelfDestroy := False;
end;

destructor TSimple.Destroy;
begin
....
if bSelfDestroy then DoSomeThing; //如果是自我释放,处理一些后事
....
end;

procedure TSimple.Test;
begin
..
if a = b then
begin
bSelfDestroy := True; //设置自我释放标志
FreeAndNil(Self); //释放
Exit; //跳出本函数
end;
...
end;

注意,如果FreeAndNil(Self)在try...except块中,要注意Abort和Exit的区别.这里用Exit跳出本函数就可以了.
 
Procedure TSaimple.Test;
begin
LoadNumA;
LoadNumB;
if NumA = NumB then
begin
FreeAndNil(Self)???;
Free;
Abort;
end;
if NumA > NumB then
ProcessNum(NumA);
end;

没有什么问题呀,担心什么?
 
我建议改成以下方式比较安全一些
TSimple = class
private
procedure Test;
public
MyVar: Pointer;
end;


procedure TSimple.Test;
begin
if True then //这里可以添加释放判断,请改成你自己的判断条件
begin
FreeAndNil(myvar^); //释放
Exit; //跳出本函数
end
else
begin
end;
end;


创建TSimple实例时:
var
Simple: TSimple;

procedure TForm1.Button1Click(Sender: TObject);
begin
Simple := TSimple.Create;
Simple.MyVar := @Simple; //必须加这句,为自释放指定对象
end;


在其它地方调用Simple时都应该这样判断
if Simple <> nil then //确保Simple没有自释放时才能调用Simple的属性和方法
begin
....
end;
 
任何时候,都不要在类里面为self调用free!!!!
不要以为FreeAndNil(self)很安全,相反,用了就死定了。
Procedure TSaimple.Test; //可以看成TSaimple.Test(self: TSaimple)
begin
LoadNumA;
LoadNumB;
if NumA = NumB then
begin
FreeAndNil(Self);
Abort;
end;
if NumA > NumB then
ProcessNum(NumA);
end;
....
aSaimple:TSaimple;
....
aSaimple.Test;//可以看成 TSaimple(aSaimple)
如果在Test里面,aSaimple指向的对象被你free了,aSaimple不会被andNil,被置空的是self!
 
楼上的是说这样会内存泄露吗??我的代码运行时用FastMM检查并没有发生泄露啊.
====
还有,我不得不用Abort退出,而不用EXIT.因为这个Test函数是被ASample的其它的方法调用的,如果用Exit退出的话,就只能退出Test函数,而继续执行调用Test的方法的方法.

不知道大家有没有其它的意见,欢迎指正
 
-_-!
这是基本的原则,不是内存泄漏的问题。
其实我还不知道你想做什么。你做出这样一个类,一个随时有可能销毁自己的类,怎么用它呢?这个类的对象,在调用对象方法时,随时可能被销毁。而对象的使用者是无法知道它是否被销毁了的。
aSaimple:=TSaimple.Create;
aSaimple.Test; //可能发生FreeAndNil(self)
if aSaimple<>nil then //aSaimple<>nil永远是真的
aSaimple.XXXX;

你在Test里面有可能做了这样的事FreeAndNil,但aSaimple这个对象指针总是指向那个对象,永远不会变成的nil的。怎么知道aSaimple这个对象还能不能用,还是说已经被销毁了?或是你准备在做了FreeAndNil(self)后就把程序结束了?
 
只听程序运行完成后毁灭自己。没有听过运行时毁灭组件
 
我的实际程序大概是这样的,我现在做一个轨道监控的系统,机车有占用的段(实际占用的轨道)和预占用的段(准备占用的轨道),预占用和占用都不能再被其它的机车分配.
在我的程序中,占用段和预占用段是由TTrain对象根据轨道的信息来由TTrain自己来分配的,也就是说TTrain自己取得段(当然前题是没有被其它的机车占用过).

实际的需要中有这样的要求,当机车驶出不需要再监控的范围后,就应该在监视屏幕中消失掉,在程序中应该就是释放此TTrain对象.只有当TTrain自己为自己分配占用和预占用段时,才能发现自己是不是要驶出监控的范围,如果是的话,应该释放这个Train对象,于是我就用了自己FreeAndNil的办法.当然也可以设置一个标志,来表示这个机车已经驶出监视的范围,然后由程序通过检查是不是需要释放而决定释放这个Train,但这样感觉程序应该定时检查所有的TTrain对象,感觉没有必要,我做的是单线程的程序,觉得这样做效率不高.才想到自销毁的办法,但却不知道这样是不是安全.
=================
对了TTrain类我从TComponentList继承做了一个TTrainList类,可以监视到TTrain的Free,
所以,程序是知道TTrain的释放的,但,关键是,在自己Free自己时,可能会发生问题.如果用了
Abort,又担心会中止掉在一起的不应该中止掉的处理.实际上,对于Abort执行后,程序停止的
当前操作的这个当前操作的概念我还是不清楚,因为它可以退到好几层函数调用之外,但我不知道它到底何时停止跳出.如果有时间请大家告诉我一下
==================
不知道这样的思路对不对,还有没有更好的思路??

=========
谢谢大家,如果给我一个差不多的答案,马上分分结帖
 
free烧毁他
 
在对象的一个事件中FREE之,会有什么问题?
 
后退
顶部