如何释放记录中的对象?

2023-12-28

我想我遇到了一个棘手的情况。我需要能够释放一个记录字段的对象。如果它是一个类,我通常会在析构函数中编写清理代码。但是由于记录类型不能引入“析构函数”,那么如何调用TObject(字段).Free; ?

我预测会有两种类型的使用:

  1. 用新记录替换记录。

    我认为这种用法很容易实现。由于记录是值类型,因此它们在赋值时被复制,因此我可以重载赋值运算符并释放旧记录拥有的对象。

    ( Edit:无法进行赋值重载。这对我来说是一个新信息..)

  2. 退出记录变量定义的范围。

    我可以想到一个释放对象的私有方法,并且可以在范围激励上手动调用该方法。但是,这是同样的问题:如何让它变得更多recordly?这种行为有点像一个班级......

这是一个示例(显然不是预期用途):

TProperties = record
  ... some other spesific typed fields: Integers, pointers etc..
  FBaseData: Pointer;

  FAdditionalData: TList<Pointer>;
  //FAdditionalData: array of Pointer; this was the first intended definition
end;

Assume,

FAdditionalData:=TList<Pointer>.Crete;

在记录构造函数中调用或通过公开访问字段在记录变量范围中手动调用,例如

procedure TFormX.ButtonXClick(Sender: TObject);
var
  rec: TProperties;
begin
  //rec:=TProperties.Create(with some parameters);

  rec.FAdditionalData:=TList<Pointer>.Create;

  //do some work with rec
end;

退出 ButtonClick 范围后rec不再是一个TList仍然保持其存在,导致内存泄漏......


如果记录中只有对象引用,那么编译器就无法帮助您。您全权负责该对象的生命周期。您不能重载赋值运算符,并且您不会收到任何范围终止的通知。

不过,您可以做的是添加一个保护接口来管理对象的生命周期。

TMyRecord = record
  obj: TMyObject;
  guard: IInterface;
end;

你需要确保TMyObject通过引用计数来管理其生命周期。例如,通过派生自TInterfacedObject.

当您初始化记录时,您将执行以下操作:

rec.obj := TMyObject.Create;
rec.guard := rec.obj;

此时,guard记录的字段现在将管理对象的生命周期。

事实上,如果你想进一步推动这个想法,你可以构建一个专用的类来保护对象的生命周期。那么就不再限制你实施IInterface在你的课堂上。网络上有很多示例来说明该技术。例如,我提供 Jarrod Hollingworth 的文章,标题为智能指针 http://members.adug.org.au/2011/12/05/smart-pointers/,巴里·凯利的标题是重新审视引用计数指针 http://blog.barrkel.com/2008/11/reference-counted-pointers-revisited.html。还有更多。这是老把戏了!

但请注意,这里是值类型和引用类型的奇怪混合体。从表面上看,记录是值类型。然而,这个类型的作用就像一种引用类型。如果记录中还有其他属于值类型的字段,那么情况会更加混乱。当您处理此类记录时,您需要非常注意这个问题。

从表面上看,在不了解更多有关您的设计的情况下,我倾向于建议您不要将对象引用放入记录中。它们更适合内部引用类型,即类。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何释放记录中的对象? 的相关文章

  • Delphi - 将字符串从 UTF-8 转换回来

    我在将 UTF 8 编码字符串转换回 delphi 可用的字符串时遇到问题 该应用程序是用 XE8 编写的 并部署在 Windows 和 OSX 上 该应用程序分别在 Windows 和 OSX 上使用 LimeLM API dll 和 d
  • 如何允许表单接受文件删除而不处理 Windows 消息?

    在 Delphi XE 中 我可以允许我的表单接受文件 拖放 但不必处理裸窗口消息吗 您不需要处理消息来实现这一点 你只需要实施IDropTarget并打电话RegisterDragDrop RevokeDragDrop 这真的非常非常简单
  • 如何将FireMonkey表单无缝嵌入VCL表单中?

    我使用了中描述的技巧这个问题 https stackoverflow com questions 7315050 delphi xe2 possible to instantiate a firemonkey form in vcl app
  • 如何将 TGifImage 中的帧提取为位图?

    下面的演示尝试在表单的画布上绘制 GIF 这不起作用 图像不会前进 如何让它发挥作用 procedure TForm1 FormCreate Sender TObject begin GIF TGIFImage Create GIF Loa
  • Delphi XE2 Firemonkey 示例应用程序未在 MAC 上运行

    我正在尝试在 Mac 上运行示例 Firemonkey 应用程序 但我在 Mac 中收到以下消息 dyld Library not loaded rpath libcgunwind 1 0 dylib Referenced from Use
  • 如何将 JSON 字符串转换为图像?

    我有一个将图像转换为 JSON 数组的应用程序 并将其保存到 blob 字段中 function getImage String var memorystream TMemoryStream jsonArray TJSONArray beg
  • 如何追踪手柄泄漏?

    在我的一个应用程序中 我观察到句柄数量不断增加 在不使用应用程序的情况下 该数字大约每秒增加一次 因此后台处理代码的某些部分一定存在句柄泄漏 我如何追踪此类泄漏 有什么工具可以帮助解决这个问题吗 跟踪句柄泄漏时要寻找哪些模式 导致手柄泄漏的
  • Delphi - 如何获取 USB 可移动硬盘和记忆棒的列表?

    在我的应用程序 Delphi 中 我需要列出所有 USB 存储设备 这些可以是闪存棒or外部存储驱动器 有一个Jvcl成分JvDriveCombo 并且它有DriveType属性 问题是我是否选择DriveType Fixed那么除了外部驱
  • Delphi 5 的哈希表实现 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 您知道 Delphi 5 的良好且免费的哈希表实现吗 我需要在哈希表中组织大量数据 并且我有点担心在网
  • 如何在Delphi中显示Vista风格的气球提示?

    在输入验证时 我使用气球提示而不是消息框 我的问题是 在 Vista 上 它们具有带圆角的旧 XP 样式 而不是较新的矩形外观 我尝试使用 CreateWindowEx 创建它们并且tooltips class32或使用 SendMessa
  • 通过套接字发送动态数组(在记录内)?

    我正在尝试直接使用 SendBuf 将记录从服务器传输到客户端 但是 该记录有一个动态数组的成员 并且我在某处 在 SOF 中 读到 发送记录时 成员必须是静态的 固定长度 但问题是 我无法确定如何我会 将来 发送许多论点 我怎么解决这个问
  • Delphi中使用FindVCLWindow调用WinHelp32(WinXP Pro SP3 32bit)

    有什么问题吗 procedure TForm1 VCLHelpClick Sender TObject var Ctrl TWinControl begin Ctrl FindVCLWindow Mouse CursorPos if Ctr
  • 在 Delphi 或 C++ Builder 中使用 Chromium Edge WebView2 [重复]

    这个问题在这里已经有答案了 既然 Microsoft Chromium Edge 已经最终确定 是否可以在 Delphi 或 C Builder 中使用它 据我了解 它是基于WebView2成分 是否有一个组件 例如TWebView2或者E
  • 将图像加载到 TImageList 并读取它们?

    我试图通过将 jpg 转换为 bmp 然后将其保存到 imagelist1 来将 jpg 加载到图像列表中 从上到下的代码片段 Selectdir 有效 fileexists 部分有效 这用于加载文件夹中的所有图像 所有图像都以 0 jpg
  • 如何比较枚举类型集

    从某个时刻开始 我厌倦了编写设定条件 and or 因为对于更多的条件或更长的变量名 重新编写会变得笨拙且烦人 所以我开始写助手这样我就可以写ASet ContainsOne ceValue1 ceValue2 代替 ceValue1 in
  • 如何从该 JAVA 文件中提取 Delphi 类以与 Android 一起使用?

    我的Delphi XE7项目需要与FTDI FT311 Android 配件芯片 http www ftdichip com Products ICs FT311D html 他们帮助提供了一个 Android 演示 其中包括他们的 JAV
  • 阻止 IDE 自动添加使用单位

    我正在将 Lazarus 项目转移到德尔福西雅图 Lazarus 项目依赖于 40 多个单元 包括控件 并具有多种应用程序 在所有项目的使用条款中 他们使用了以下内容 uses Classes SysUtils Forms Controls
  • 使用 PutBlock 并将字节数组全部设置为零的 EIPHTTPProtocolExceptionPeer 异常

    使用 Delphi XE2 Update 3 我在将零字节块上传到 Azure 时遇到问题 当我说零字节时 我指的是每个元素设置为零的字节数组 不是零长度 例如 var ConInfo TAzureConnectionInfo RespIn
  • Delphi XE7 Android 全屏(隐藏软键)

    如何在XE7中全屏显示 隐藏顶部 标题 和底部 软键 工具栏 在 XE6 中 我可以通过在应用程序部分写入来调整 AndroidManifest 以使我的应用程序全屏显示并且没有操作栏 android theme android style
  • Delphi 中表单分发与其生命周期相关的接口对象的安全方法?

    我有一个 Delphi 表单 它提供接口对象背后的功能 代码的其他部分也通过属于该表单的属性获取引用 我无法将接口功能委托给子对象 因为太多的功能是由表单上的控件 组件提供的 我无法使用 TAggregateObject 或 TContai

随机推荐

  • 如何查看定位服务是否开启?

    我正在 Android 操作系统上开发一个应用程序 我不知道如何检查定位服务是否启用 我需要一个方法 如果启用它们 则返回 true 如果未启用 则返回 false 因此在最后一种情况下 我可以显示一个对话框来启用它们 您可以使用以下代码检
  • 如何在 SwiftUI 中删除“Form”的顶部空间?

    如何顶部对齐Form在一个NavigationView 当我删除时 我有以下内容NaviagationView从身体上来说 Form顶部对齐 和NavigationView在适当的位置 我得到了之间的间距 添加红色框以显示空间 我可以用 p
  • OpenFileDialog.ShowDialog() 抛出异常?

    我试图从我的 WPF 视图模型命令之一显示一个对话框 但是当我调用ShowDialog 它抛出一个System ArgumentException 我想知道是否有人可以给我提示为什么 这是我的代码 Public ReadOnly Prope
  • Post重写java中组件的paint方法

    在java awt或swing中 当您想要更改某些组件的绘制时 通常必须重写方法paint Graphics g 在awt中 或paintComponent Graphics g 在swing中 这通常 也许总是 我不确定 在创建组件时完成
  • 来自asp.net 会员身份验证的userid?

    我正在使用 asp net 登录控件进行用户身份验证 我的应用程序的许多表中也有 userID 目前 开发目的 userID 是我正在编写的 int 但是 我想开始在表中使用框架的用户 ID 在哪里以及如何访问实际的用户 ID 及其数据类型
  • 无法加载扩展类 org.apache.cxf.ws.policy.AssertionBuilderRegistryImpl

    我正在为 cxf 配置的类上运行 junit 我收到这个错误 导致 org apache cxf bus extension ExtensionException 无法加载扩展类org apache cxf ws policy Assert
  • python - 读取不同编码的各种文件

    我建了一个Python 隐写器 https codereview stackexchange com questions 165163 python steganographer using pil隐藏着UTF 8图像中的文本 效果很好 我
  • using 语句和受保护的构造函数[重复]

    这个问题在这里已经有答案了 class A protected A int struct B public A public using A A void print B b int main int argc char argv prin
  • 允许用户池中的 Cognito 用户访问 S3 存储桶的存储桶策略

    我正在尝试向我的存储桶添加存储桶策略 因为我的存储桶位于根 aws 账户中 并且我想限制根账户下的其他用户 角色等访问我的存储桶 但我的用户中的特定 Cognito 用户除外水池 我不想也使用身份池 我只想将 Cognito 用户称为我的存
  • Netty的并发编码

    编码器的encode方法会并发执行吗 我观察到编码方法可能是由不同线程并发的 管道定义为 Channels pipeline idleHandler new AmfDecoder
  • MongoDB 我应该将用户放在管理数据库还是本地数据库中

    MongoDB 中是否有关于我应该将数据库用户放在哪里的最佳实践 我刚刚设置了一个本地 MongoDB 服务器 并在管理数据库中添加了用户 并授予他们对 他们的 我的意思是用户有权访问的唯一数据库 数据库的访问权限 您认为将用户放入 他们的
  • PHP删除具有特定键重复值的关联数组的数组[重复]

    这个问题在这里已经有答案了 我有一个关联数组的数组 array xxx 0 gt array 3 group id gt 2 contact gt foo contact email gt email protected cdn cgi l
  • 隐藏/不可见 Matplotlib 图

    我有一个问题 不确定它是否困难 但我尝试用谷歌搜索答案 没有什么值得的 我的图形是全局的 可以在所有线程中访问 但它出现在程序的开头 我想在脚本的开头隐藏或使其不可见 然后在代码中的某一点使其可用或可见 有没有像visible False之
  • Html 5 本地存储在 Firefox 中不持久

    我做了一个简单的功能 localStorage setItem foo bar alert localStorage getItem foo 如果我像这样运行它就可以了 如果我在运行一次后删除第一行并且只允许这个 alert localSt
  • 如何在反应中为滑动器创建自定义导航按钮?

    Swiper React 有一个文档 但没有解释如何添加自定义导航按钮 我尝试了这个但没有成功 我正在使用 swiper 8 0 5
  • 使用 C# 在 html 文档中抓取由 JavaScript 动态生成的数据

    如何使用 C 抓取 html 文档中由 JavaScript 动态生成的数据 Using WebRequest and HttpWebResponse在C 库中 我能够以字符串形式获取整个html源代码 但困难在于源代码中不包含我想要的数据
  • 触发自定义类事件后,表单未更新

    我遇到一个问题 即使我看到事件触发 我的主表单也没有更新 让我解释一下情况并分享一些我的代码 因为我是业余爱好者 所以我确信这些代码会很糟糕 我创建了一个类来获取在后台运行进程的设置 我在该类中添加了一些自定义事件 以便我可以在表单中使用它
  • C# 泛型无法识别类型

    我不明白为什么下面的代码返回一个Cannot resolve method Write T 这对我来说似乎很明确 private static void WriteToDisk
  • 如何将您的代码上传到 Google Glass?

    我正在学习android和GDK 我安装了 Android开发者工具 和 SDK管理器 我制作了第一个 hello world 应用程序 但我不知道如何从 Windows 7 PC 连接到我的 Google Glass 来上传代码 如果有人
  • 如何释放记录中的对象?

    我想我遇到了一个棘手的情况 我需要能够释放一个记录字段的对象 如果它是一个类 我通常会在析构函数中编写清理代码 但是由于记录类型不能引入 析构函数 那么如何调用TObject 字段 Free 我预测会有两种类型的使用 用新记录替换记录 我认