Delphi-判断一个对象是否释放,改造官方的Assigned
直接上例子了,基础知识自己去了解,首先定义一个类:
TPerson = class
public
name: string;
age: Integer;
constructor Create(name: string; age: Integer);
end;
constructor TPerson.Create(name: string; age: Integer);
begin
Self.name := name;
Self.age := age;
end;
例子1,首先了解Free,仅仅是销毁堆中数据,栈中变量的值依然是堆中的地址:
procedure TForm3.btn1Click(Sender: TObject);
var
ps: TPerson;
begin
ps := TPerson.Create('小李', 10);
ps.Free; //这里调用Free,堆中的数据已经被释放,但是ps这个指针的值还是堆中对象的地址
if Assigned(ps) then //Assigned方法,当ps指针的值为nil的时候,才返回False,由于ps的值不为nil,这里显然会返回True
begin
mmo1.Lines.Add('yes');
mmo1.Lines.Add(ps.name); //这里产生了Av错误,原因是ps堆中的对象已经被释放
end else begin
mmo1.Lines.Add('no');
end;
end;


例子2,知道即使你不创建实例,Assigned依然是true;
procedure TForm3.btn3Click(Sender: TObject);
var
p: TPerson;
begin
//p不初始化,会自由随机分配一个地址和值,值也是原来的自由值,不一定是nil,通常都不是nil
if Assigned(p) then
begin
//只要p指针的值不是nil,这里就会返回true,所以是yes
mmo1.Lines.Add('yes');
end else begin
mmo1.Lines.Add('no');
end;
end;


例子3:对例子1进行改造,使用FreeAndNil,将堆中数据释放,同时将栈中指针的值变为nil;
procedure TForm3.btn3Click(Sender: TObject);
var
ps: TPerson;
begin
ps := TPerson.Create('小李', 10);
FreeAndNil(ps); //指针的值也变成nil了
if Assigned(ps) then
begin
mmo1.Lines.Add('yes');
end else begin
mmo1.Lines.Add('no'); //此时就自然到这里了
end;
end;



例子4,最后一个例子,得出官方的Assigned 不是我们需要的:
procedure TForm3.btn4Click(Sender: TObject);
var
ps, ps1: TPerson;
begin
ps := TPerson.Create('小李', 10);
ps1 := ps;
FreeAndNil(ps);
if Assigned(ps) then
begin
mmo1.Lines.Add('yes');
end else begin
mmo1.Lines.Add('no'); //ps指针的值是nil了,所以no
end;
if Assigned(ps1) then
begin
mmo1.Lines.Add('yes'); //ps1指针的值不是nil
//mmo1.Lines.Add(ps1.name); //这里就会报错,因为ps堆中的数据已经释放
end else begin
mmo1.Lines.Add('no');
end;
//显然上面不是我们要的结果,使用我们自己的函数
if AssignedEx(ps1, TPerson) then
begin
mmo1.Lines.Add('yes');
end else begin
mmo1.Lines.Add('no'); //由于ps1指向的堆中数据已经不存在,这里会no
end;
end;

好了综上得出官方的Assigned 有点简陋,不是我们需要的,引出我们的修改版:
/// <summary>
/// 判断实例释放释放
/// </summary>
/// <param name="AVar">实例变量</param>
/// <param name="className">实例类型</param>
function AssignedEx(AVar: TObject; AClass: TClass): Boolean;
begin
//首先判断变量指针的值是否为nil
if not Assigned(AVar) then
begin
Exit(False);
end;
//判断堆中的数据是否是当前类
try
//若AVar指向的堆中数据已释放,则这里调用.ClassName会AV异常
if AVar.ClassName = AClass.ClassName then
begin
Exit(True);
end else begin
Exit(False);
end;
except
//有异常说明堆中已经被释放掉了
Exit(False);
end;
end;
==========================================================
最后贴上全部测试代码:
全部测试代码
unit Unit3;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm3 = class(TForm)
mmo1: TMemo;
btn1: TButton;
btn2: TButton;
btn3: TButton;
btn4: TButton;
btn5: TButton;
procedure btn1Click(Sender: TObject);
procedure btn2Click(Sender: TObject);
procedure btn3Click(Sender: TObject);
procedure btn4Click(Sender: TObject);
procedure btn5Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TPerson = class
public
name: string;
age: Integer;
constructor Create(name: string; age: Integer);
end;
var
Form3: TForm3;
implementation
{$R *.dfm}
constructor TPerson.Create(name: string; age: Integer);
begin
Self.name := name;
Self.age := age;
end;
/// <summary>
/// 判断实例释放释放
/// </summary>
/// <param name="AVar">实例变量</param>
/// <param name="className">实例类型</param>
function AssignedEx(AVar: TObject; AClass: TClass): Boolean;
begin
//首先判断变量指针的值是否为nil
if not Assigned(AVar) then
begin
Exit(False);
end;
//判断堆中的数据是否是当前类
try
//若AVar指向的堆中数据已释放,则这里调用.ClassName会AV异常
if AVar.ClassName = AClass.ClassName then
begin
Exit(True);
end else begin
Exit(False);
end;
except
//有异常说明堆中已经被释放掉了
Exit(False);
end;
end;
procedure TForm3.btn1Click(Sender: TObject);
var
ps: TPerson;
begin
ps := TPerson.Create('小李', 10);
ps.Free; //这里调用Free,堆中的数据已经被释放,但是ps这个指针的值还是堆中对象的地址
if Assigned(ps) then //Assigned方法,当ps指针的值为nil的时候,才返回False,由于ps的值不为nil,这里显然会返回True
begin
mmo1.Lines.Add('yes');
mmo1.Lines.Add(ps.name); //这里产生了Av错误,原因是ps堆中的对象已经被释放
end else begin
mmo1.Lines.Add('no');
end;
end;
procedure TForm3.btn2Click(Sender: TObject);
var
p: TPerson;
begin
//p不初始化,会自由随机分配一个指针,指针的值也是原来的自由值,不一定是nil
if Assigned(p) then
begin
//只要p指针的值不是nil,这里就会返回true,所以是yes
mmo1.Lines.Add('yes');
end else begin
mmo1.Lines.Add('no');
end;
end;
procedure TForm3.btn3Click(Sender: TObject);
var
ps: TPerson;
begin
ps := TPerson.Create('小李', 10);
FreeAndNil(ps); //指针的值也变成nil了
if Assigned(ps) then
begin
mmo1.Lines.Add('yes');
end else begin
mmo1.Lines.Add('no'); //此时就自然到这里了
end;
end;
procedure TForm3.btn4Click(Sender: TObject);
var
ps, ps1: TPerson;
begin
ps := TPerson.Create('小李', 10);
ps1 := ps;
FreeAndNil(ps);
if Assigned(ps) then
begin
mmo1.Lines.Add('yes');
end else begin
mmo1.Lines.Add('no'); //ps指针的值是nil了,所以no
end;
if Assigned(ps1) then
begin
mmo1.Lines.Add('yes'); //ps1指针的值不是nil
//mmo1.Lines.Add(ps1.name); //这里就会报错,因为ps堆中的数据已经释放
end else begin
mmo1.Lines.Add('no');
end;
//显然上面不是我们要的结果,使用我们自己的函数
if AssignedEx(ps1, TPerson) then
begin
mmo1.Lines.Add('yes');
end else begin
mmo1.Lines.Add('no'); //由于ps1指向的堆中数据已经不存在,这里会no
end;
end;
procedure TForm3.btn5Click(Sender: TObject);
var
ps, ps1: TPerson;
begin
ps := TPerson.Create('小李', 10);
ps1 := ps;
FreeAndNil(ps);
if Assigned(ps) then
begin
mmo1.Lines.Add('yes');
end else begin
mmo1.Lines.Add('no'); //ps指针的值是nil了,所以no
end;
if Assigned(ps1) then
begin
mmo1.Lines.Add('yes'); //ps1指针的值不是nil
//mmo1.Lines.Add(ps1.name); //这里就会报错,因为ps堆中的数据已经释放
end else begin
mmo1.Lines.Add('no');
end;
//显然上面不是我们要的结果,使用我们自己的函数
if AssignedEx(ps1, TPerson) then
begin
mmo1.Lines.Add('yes');
end else begin
mmo1.Lines.Add('no'); //由于ps1指向的堆中数据已经不存在,这里会no
end;
end;
end.
Delphi-判断一个对象是否释放,改造官方的Assigned的更多相关文章
- Delphi中关于资源释放(Free,Relealse,FreeAndNil)
根据日常编程经验,得出一些Delphi中关于资源释放的体会. 假如有对象Obj为TObject类型: 1) Obj.Free直接释放资源后,调用OnDestroy事件,但是没有将Obj指针值置为Nil ...
- win10 uwp 如何判断一个对象被移除
原文:win10 uwp 如何判断一个对象被移除 有时候需要知道某个元素是否已经被移除,在优化内存的时候,有时候无法判断一个元素是否在某个地方被引用,就需要判断对象设置空时是否被回收. 本文告诉大家一 ...
- 2018-8-10-win10-uwp-如何判断一个对象被移除
title author date CreateTime categories win10 uwp 如何判断一个对象被移除 lindexi 2018-08-10 19:16:50 +0800 2018 ...
- java面试一日一题:如何判断一个对象是否为垃圾对象
问题:请讲下在java中如何判断一个对象是否为垃圾 分析:该问题主要考察对java中的垃圾回收,用什么方式去识别一个对象是垃圾: 回答要点: 主要从以下几点去考虑, 1.GC回收的是什么,回收发生在内 ...
- JS心得——判断一个对象是否为空
判断一个对象是否为空对象,本文给出三种判断方法: 最常见的思路,for...in...遍历属性,为真则为"非空数组":否则为"空数组" 2.通过JSON自带的. ...
- Delphi的分配及释放---New/Dispose, GetMem/FreeMem及其它函数的区别与相同
转载自:http://www.cnblogs.com/qiusl/p/4028437.html?utm_source=tuicool 我估摸着内存分配+释放是个基础的函数,有些人可能没注意此类函数或细 ...
- delphi.memory.分配及释放---New/Dispose, GetMem/FreeMem及其它函数的区别与相同
我估摸着内存分配+释放是个基础函数,有些人可能没注意此类函数或细究,但我觉得还是弄明白的好. 介绍下面内存函数前,先说一下MM的一些过程,如不关心可忽略: TMemoryManager = recor ...
- javascript-如何判断一个对象为数组
Q:如何判断一个对象是否为数组? A1:判断对象的constructor是否指向Array, 接着判断对应的特殊属性,如length,splice之类.这个很容易冒充. A2:使用instanceof ...
- delphi 判断是否出现滚动条
delphi 判断是否出现滚动条 if (GetWindowlong(Stringgrid1.Handle, GWL_STYLE) and WS_VSCROLL) <> 0 the ...
- 使用js判断一个对象是否为空 比如 obj={}
今天使用到js判断一个对象是否为空,js没有封装好的方法,这里最好的办法就是使用jquery里面的封装好的方法 $.isEmptyObject(obj)
随机推荐
- 【RK3399】2.制作ubuntu20.04 roomfs
firefly自带的文件系统,由于缺少一些基本功能模块,因此,我们可以自己手动制作一个ubuntu20.04的文件系统. 下载Ubuntu根文件系统 http://cdimage.ubuntu.com ...
- 3D编程模式:开篇
大家好~现在开始新的系列文章:3D编程模式系列 本系列会介绍从我的实际开发经验中抽象提炼出来的编程模式,大家可直接应用它们到3D引擎开发.编辑器开发等领域中 相关资料: 课程录像回放 代码和课程ppt ...
- Blazor模式讲解
Blazor的三种模式 Blazor Server: Blazor Server在 ASP.NET Core 应用中支持在服务器上托管 Razor 组件. 可通过 SignalR 连接处理 UI 更新 ...
- 让vs自动提示没有using的类
默认情况下,没有using的类,敲代码时没有智能提示,需要在[工具]->[选项]中开启
- AspNetCore在docker里访问Oracle数据库的坑:ORA-01882: timezone region not found
哦吼 之前刚说了尝试了使用docker来部署AspNetCore应用,结果这才刚上班就遇到问题了= =- 我这项目用的数据库是Oracle,之前直接运行没啥问题,但放在docker里运行就报了这个错误 ...
- [转帖]经典的 Fork 炸弹解析
https://linux.cn/article-5685-1.html Jaromil 在 2002 年设计了最为精简的一个 Linux Fork 炸弹,整行代码只有 13 个字符(包括空格在内,空 ...
- JDBC针对SQLServer的sendStringParametersAsUnicode=false的验证
JDBC针对SQLServer的sendStringParametersAsUnicode=false的验证 背景 部分客户的SQLServer数据库出现了大量死锁的情况. 虽然部分客户并没有反馈死锁 ...
- [转帖]学习如何编写 Shell 脚本(进阶篇)
https://juejin.cn/post/6935365727205457928 前言 在<学习如何编写 Shell 脚本(基础篇)>一文中已经讲解了 Shell 脚本编程的基础知识, ...
- [转帖]LSM树详解
https://zhuanlan.zhihu.com/p/181498475 LSM树(Log-Structured-Merge-Tree)的名字往往会给初识者一个错误的印象,事实上,LSM树并不像B ...
- 【转帖】浅析经典JVM垃圾收集器-Serial/ParNew/Parallel Scavenge/Serial Old/Parallel Old/CMS/G1
https://zhuanlan.zhihu.com/p/481256418 在讲述垃圾收集器之前,我们得先知道JVM中常见的垃圾收集算法有什么,具体请参考我的这篇博文.如果说收集算法是内存回收的方法 ...