Delphi中destroy, free, freeAndNil, release用法和区别

Delphi中destroy, free, freeAndNil, release用法和区别

1)destroy:虚方法

释放内存,在Tobject中声明为virtual,通常是在其子类中override
它,且要加上inherited关键字,才能保证派生类对象正确地被销毁;
但destroy一般不能直接用,为什么?
当一个对象为nil,我们仍然调用destroy,会产生错误。因为destroy是虚方法,它要根据对象中的头四个字节找到虚拟方法表Vmt的入口地址,从而找到destroy的入口地址,所以此时对象一定要存在。但free就是静态方法,它根据对象引用/指针的类型来确定,即使对象本身不存在也不会产生异常,而且在free中有判断对象是否存在的操作,所以一般的情况下都用Free来释放对象。

2)free:静态方法

测试对象是否为nil,
不为nil则调用destroy。下面是free的Delphi代码:
procedure TObject.Free;
begin
 
if Self <> nil then
   
Destroy;
end;
一静一动,取长补短,岂不妙哉!
但是调用对象的Destroy只是把对象销毁了,但并没有把对象的引用设为nil,这需要程序员来完成,不过自从Delphi5之后,在sysUtils单元中提供了一个freeAndNil。

3)freeAndNil:一个独立的函数,不属于任何对象,非对象方法,非类方法。

procedure
FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp :=
TObject(Obj);
  Pointer(Obj) := nil;
 
Temp.Free;
end;

建议大家用它代替free/Destroy,以便确保正确地释放对象。

4)release:TcustomForm中定义的静态方法。

当窗口中所有的事件处理完之后,才调用free函数。常用在销毁窗口,而在这个窗口中事件处理需要一定的时间的时候,用这个方法能确保窗口事件处理完之后才销毁窗口。
下面是TCustomForm.Release的Delphi源代码:
procedure
TCustomForm.Release;
begin
  PostMessage(Handle, CM_RELEASE, 0,
0);
  //向窗口发CM_RELEASE消息到消息队列,当所有的窗口事件消息处理完之后,
 
//再调用CM_RELEASE消息处理过程CMRelease
end;
再看看下面CM_RELEASE消息处理过程CMRelease的定义:
procedure
CMRelease(var Message: TMessage); message CM_RELEASE;
procedure
TCustomForm.CMRelease;
begin
  Free; //最后还是free;
end;

时间: 2024-10-17 17:05:04

Delphi中destroy, free, freeAndNil, release用法和区别的相关文章

oracle中delete drop truncate的用法和区别

数据库的运维中,经常会遇到delete drop truncate的操作,那么如何去把握它们的用法和区别呢? 比如当数据库空间爆满,已经增长到存储空间单个存储文件的最大值32G.你需要通过一些办法释放掉表空间或者扩容表空间来解决问题. 一般当系统中大量使用分区表,而针对分区表清除数据,是不会释放表空间的,必须把分区drop掉,才会释放空间. 下面我们具体了解一下这三个命令: 一.delete 1.delete是DML,执行delete操作时,每次从表中删除一行,并且同时将该行的的删除操作记录在r

Java中super和this的用法和区别

许多同学在学习Java时分不清楚this和super的用法和区别,今天偶然发现一片加精的博文,看完内容准备自己也写下来积累一下 1.如果想在子类的构造方法中调用父类的构造方法,必须在子类的构造方法中使用super();且必须将其放在首句 public class L1106Demo06 { public static void main(String[] args) { lake M=new lake(); } } /*super方法的用法1. * 在子类的构造方法中若果要想要调用父类的构造方法

php中str_replace和str_ireplace的用法和区别

str_replace() 函数 定义:使用一个字符串替换字符串中的另一些字符,对大小写敏感的搜索 语法: str_replace(find,replace,string,count) str_ireplace() 函数 定义:使用一个字符串替换字符串中的另一些字符,对大小写不敏感的搜索 语法:str_ireplace(find,replace,string,count) str_replace详解 在都不使用数组时,该函数直接使用replace替换所有的search并返回替换后的字符串.如:s

java中抽象类和接口的用法和区别

一.抽象类 1.抽象类 包含一个抽象方法的类就是抽象类 2.抽象方法 声明而未被实现的方法,抽象方法必须使用abstract关键词字声明 public abstract class People { //关键词abstract,声明该类为抽象类 public int age; public void Num() { } public abstract Name(); //声明该方法为抽象方法 } 3.抽象类被子类继承,子类(如果不是抽象类)必须重写抽象类中的所有抽象方法 4.抽象类不能被直接实例

脚本引用中使用defer和async用法和区别

是的,就是在页面脚本引用的时候设置defer或者async,为什么会有这两个属相来辅助脚本加载那,因为浏览器在遇到script标签的时候,文档的解析会停止,不再构建document,有时打开一个网页上会出现空白一段时间,浏览器显示是刷新请求状态(也就是一直转圈),这就会给用户很不好的体验,defer和async的合理使用就可以避免这个情况,而且通常script的位置建议写在页面底部(移动端应用的比较多,这两个都是html5中的新属性). 1.默认引用 script:<script type=&quo

JS中substr和substring的用法和区别

一.substr 方法 返回一个从指定位置开始的指定长度的子字符串.string.substr(start [, length ]) 注意: length可选项.如 length 为 0 或负数,将返回一个空字符串.如果没有指定该参数,则子字符串到 string 的最后. let words = $("#wxWords").val(); let first = words.substr(0, 1) //截取第一个文字 let second = words.substr(1, 1) //

JS中!=、==、!==、===的用法和区别

1.对于string,number等基础类型,==和===是有区别的 1)不同类型间比较,==之比较"转化成同一类型后的值"看"值"是否相等,===如果类型不同,其结果就是不等 2)同类型比较,直接进行"值"比较,两者结果一样 2.对于Array,Object等高级类型,==和===是没有区别的 进行"指针地址"比较 3.基础类型与高级类型,==和===是有区别的 1)对于==,将高级转化为基础类型,进行"值&quo

Delphi中的Free和Nil和freeandnil函数

Delphi中的Free和Nil 在Delphi中释放对象资源时一般用Obj.Free(Obj为一个实例名),不过程Delphi中还有一个FreeAndNil(对象名)函数,那么用哪个好呢?Free和Nil的本质又都是什么呢? 在Delphi中一个对象名只是一个指向该对象的指针,可以有多个指针指向同一个对象地址.Nil是将指针置空,而Free则将指针指向的对象销毁掉.如下所示: Obj.Free; //将Obj所指向的对象销毁. Obj:= nil; //将Obj指针置空.如果将上面的一句放在后

Delphi中实现ListView滚动条的换肤方案

首先是要骗过WM_NCPAINT消息.这个十分容易.WM_NCPAINT消息的wParam是一个区域的句柄.当它不为1时,从它里面CLIP掉滚动条的区域,再传给原窗口过程即可.当它为1时,创建一个包含控件全客户区域的Region,再从中CLIP掉滚动条的区域,传给原窗口过程.然后是WM_HSCROLL和WM_VSCROLL消息.在调用原窗口过程之前需要去掉窗口的WS_HSCROLL和WS_VSCROLL样式,否则窗口过程就会在消息中绘制滚动条.调用后需要恢复.同时为避免窗口在WM_STYLECH