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)
随机推荐
- SpringCloud学习 系列二、 简介
系列导航 SpringCloud学习 系列一. 前言-为什么要学习微服务 SpringCloud学习 系列二. 简介 SpringCloud学习 系列三. 创建一个没有使用springCloud的服务 ...
- <vue 基础知识 4、计算属性computed>
代码结构 一. 计算属性简单使用 1.效果 2.代码 01-计算属性简单用法.html <!DOCTYPE html> <html lang="en"&g ...
- NCC Mocha v0.10 发布, .NET 开发的基于 OpenTelemetry 的 APM 系统
目录 项目简介 项目进度 v0.10 发布内容 项目背景 平台功能 技术架构 v0.10 快速体验 启动项目 Trace 数据的发送 配置 Jaeger 数据源 Trace 数据的查询 项目简介 Mo ...
- SV 数据类型-2
动态数组 数组定义的时候不用给定数组元素个数 动态数组实例 例1 队列
- Prime Time-02
Timing Constrain clk3和clk4 - 异步 clk2和clk1 - 同步 有四个clk,所以要设置四个clk的周期 latency - Net delay,走线的延时 uncert ...
- VS中多个源文件中只运行其中特定文件
1.问题 有时候一个项目中创建了多个源文件,但是我只想运行其中的一个,一起运行就会出现多个main入口的问题 2.解决方式 2.1 右键要排除的文件,点击属性 2.2 从生成中排除一项中选择是即可 2 ...
- 【TouchGFX】visua studio 自定义路径宏
很好奇 touchgfx 的 visual studio 工程文件中路径符号 $(TouchGFXReleasePath)是哪里定义的,经查这就是一个宏替换 自定义宏方式
- CoreDNS -- DNS服务与服务发现
CoreDNS -- DNS服务与服务发现 DNS服务器 手册:https://coredns.io/manual/toc/ Github:https://github.com/coredns/cor ...
- [转帖]jmeter之foreach循环控制器-03篇
上篇我们通过正则表达式获取到了一组数据,那么怎么来用呢?下面就用foreach控制器来使用结果,如下图所示 然后再foreach控制器里添加要循环的请求,我们模拟百度搜索,value填入${id} 然 ...
- [转帖]Tomcat maxKeepAliveRequests
https://www.cnblogs.com/turn2i/p/10480088.html 在写这个问题前,其实我是为了分析项目碰到的一个tcp close wait问题.这个问题就不在这里讲了. ...