(delphi11最新学习资料) Object Pascal 学习笔记---第11章第1节 (Weak 和 Unsafe 类型接口引用)

11.1.4 Weak 和 Unsafe 类型接口引用

​ 从 Delphi 10.1 Berlin 开始,Object Pascal 语言对接口引用的管理进行了优化。实际上,Object Pascal 语言提供了不同类型的引用:

  • 常规引用在分配和释放时分别递增和递减对象引用计数,最终在引用计数为零时释放对象。

  • 弱引用(标有[weak]修饰符)不会增加所引用对象的引用计数。这些引用是完全可管理的,因此如果被引用对象被销毁,它们会被自动设置为nil。

  • 不安全引用(标有[unsafe]修饰符)不会增加其引用对象的引用计数,并且不受管理–这与基本指针没有太大区别。

    注解 弱引用和不安全引用的使用最初是作为移动平台 ARC 内存管理支持的一部分引入的。由于 ARC 现已淘汰,因此该功能仅适用于接口引用。

​ 通常引用计数在处于激活状态的情况下,你可以使用如下代码,该代码依赖引用计数来释放临时对象:

procedure TForm3.Button2Click(Sender: TObject);
var
   OneIntf: ISimpleInterface;
begin
   OneIntf := TObjectOne.Create;
   OneIntf.DoSomething;
end;

​ 如果对象有一个标准的引用计数实现,而您想创建一个不计入引用总数的接口引用,该怎么办?现在,您可以通过在接口变量声明中添加 [unsafe] 属性来实现这一目的,将上面的代码更改为:

procedure TForm3.Button2Click(Sender: TObject);
var
   [unsafe] OneIntf: ISimpleInterface;
begin
   OneIntf := TObjectOne.Create;
   OneIntf.DoSomething;
end;

​ 这并不是一个好主意,因为上述代码会导致内存泄漏。通过禁用引用计数,当变量离开作用域时,什么也不会发生。在某些情况下,这样做是有好处的,因为你仍然可以使用接口,而不会触发额外的引用。换句话说,不安全引用就像指针一样,不需要额外的编译器支持。
​ 现在,在你打算使用[unsafe] 属性而不增加引用计数的时候,请考虑一下,在大多数情况下,还有另一种更好的选择:使用弱(weak)引用。弱引用也可以避免增加引用计数,但它们是受管理的。这意味着系统会跟踪弱引用,如果实际对象被删除,系统会将弱引用设置为nil。相反,如果使用不安全引用,则无法知道目标对象的状态(这种情况称为悬挂引用)。

​ 弱引用在哪些情况下有用?一个典型的情况是两个对象相互引用。事实上,在这种情况下,该对象会武断地增加其他对象的引用计数,并导致对象基本上会永远被保留在内存中(随着引用计数被设置为 1),即使对象变得不可访问也是如此。

​ 举例来说,下面的接口接受对另一个同类型接口的引用,而类通过内部引用实现这一个功能:

type
  ISimpleInterface = interface
    procedure DoSomething;
    procedure AddObjectRef(Simple: ISimpleInterface); 
  end;
  
  TObjectOne = class(TInterfacedObject, ISimpleInterface) 
  private
  	AnotherObj: ISimpleInterface;
  public
    procedure DoSomething;
    procedure AddObjectRef(Simple: ISimpleInterface);
  end;

​ 如果创建两个对象并交叉引用,就会导致内存泄漏:

var
  One, Two: ISimpleInterface;
begin
  One := TObjectOne.Create;
  Two := TObjectOne.Create;
  One.AddObjectRef(Two);
  Two.AddObjectRef(One);

​ 现在,在Delphi中的解决方案是将私有字段 AnotherObj 标记为弱引用(weak interface reference):

private
  [weak] AnotherObj: ISimpleInterface;

​ 有了这一改动,在将对象作为参数传递给 AddObjectRef 调用时,引用计数不会被修改,而是保持为 1,当变量离开作用域时,引用计数会归零,从而将对象从内存中释放出来。

​ 现在有了这一功能,在许多其他类似情况下都变得非常方便,尽管底层实现非常复杂。弱引用是一项重要的功能,但要完全掌握它还需要进一步的努力。此外,由于弱引用是受管理的(而不安全引用则不受管理),因此在运行时也会产生一些代价。

​ 有关接口的弱引用及其工作原理的更多信息,请参阅第 13 章 "对象与内存 "中的 "内存管理与接口 "一节。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/601385.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PyCharm怎么安装Comate与使用示范

目录 简单介绍Comate 安装步骤详解 Comate使用示范详解 使用总结 简单介绍Comate Baidu Comate智能编码助手是一款基于文心大模型打造的编码辅助工具,具备多重优势,包括代码智能、应用场景丰富、创造价值高、广泛应用等。它能帮助开发者提升编码效率…

数仓开发中期:理论巩固

一、数仓以及商业智能(Data Warehousing and Business Intelligence, DW/BI)系统 1.1数据操作和数据获取的区别 对所有组织来说,信息都是其最重要的财富之一。信息几乎总是用作两个目的:操作型记录的保存和分析型决策的制定。简单来说&…

关于vs2019 c++ STL 中容器的迭代器的 -> 运算符的使用,以 list 双向链表为例

(1)如下的结构体 A ,若有指针 p new A() ;则可以使用 p->m , p->n 解引用运算符。 struct A { int m ; int n; } 对于 STL 中提供的迭代器,提供了类似于指针的功能。对迭代器也可以使用 -> 运算…

ElasticSearch知识点汇总

1、ES中的​​​​​​​倒排索引是什么。 倒排索引,是通过分词策略,形成了词和文章的映射关系表,这种词典映射表即为倒排索引 2、ES是如何实现master选举的。 选举过程主要包括以下几个步骤: 心跳检测: 每个节点…

docker安装elasticsearch:7.17.21

docker安装elasticsearch:7.17.21 下载对应版本的docker镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:7.17.21启动容器 docker run --name elasticsearch-test -p 9200:9200 -p 9300:9300 -e "discovery.typesingle-node" -t docker.elastic.…

学习通下载PDF资源

今天突然发现,学习通的pdf资源居然是没有下载入口的,这整的我想cv一下我的作业都搞不了,于是我一怒之下,怒了一下。 可以看到学习通的pdf资源是内嵌在网页的,阅读起来很不方便,虽然他内置了阅读器&#xf…

如何做好一个活动策划?

活动策划的关键要素是什么? 首先,要明确一个概念:做活动就是走钢丝,没有保险的高空走钢丝!因为,活动没有“彩排”,只有现场"直播”! 无论什么类型的活动,人数是50人还是2000人,也不论预算…

Linux网络编程(一) 网络基础

一、一些概念 1.1、局域网与广域网 局域网:局域网将一定区域内的各种计算机、外部设备和数据库连接起来形成计算机通信的私有网络。广域网:又称广域网、外网、公网。是连接不同地区局域网或城域网计算机通信的远程公共网络。 1.2、IP IP地址本质就是…

某制造公司屋顶分布式光伏发电案例分享--分布式光伏电力监控系统解决方案

安科瑞薛瑶瑶18701709087/17343930412 ★分布式光伏监控系统 分布式光伏监控电力系统遵循安全可靠、经济合理原则,满足电力系统自动化总体规划要求,且充分考虑光伏发电的因素,对分布式光伏发电、用电进行集中监控、统一调度、统一运维、满足…

苍穹外卖项目---------收获以及改进(5-6天)

①HttpClient 核心作用:在java编码中发送http请求 第一步:引入依赖 第二步:使用封装一个工具类 package com.sky.utils;import com.alibaba.fastjson.JSONObject; import org.apache.http.NameValuePair; import org.apache.http.client.co…

向各位请教一个问题

这是菜鸟上的一道题目,单单拿出来问问大家,看看能不能解惑 ,谢谢各位! 题目25:求12!3!...20!的和 解题思路:这个题不知道为什么我用DEV C 5.11显示出来为0.000000,可能版本有问题?&a…

【JVM】内存结构

内存结构 Java 虚拟机定义了若干种程序运行期间会使用到的运行时数据区,其中有一些会随着虚拟机启动而创建,随着虚拟机退出而销毁。另外一些则是与线程一一对应的,这些与线程一一对应的数据区域会随着线程开始和结束而创建和销毁。 线程私有…

Agent AI智能体:我们的生活即将如何改变?

你有没有想过,那个帮你设置闹钟、提醒你朋友的生日,甚至帮你订外卖的智能助手,其实就是Agent AI智能体?它们已经在我们生活中扮演了越来越重要的角色。现在,让我们一起想象一下,随着这些AI智能体变得越来越…

【Ansiable】ansible的模块和主机清单

Ansible Ansible是一个基于Python开发的配置管理和应用部署工具,现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点,Pubbet和Saltstack能实现的功能,Ansible基本上都可以实现。 Ansible能批量配置、部署、管理上千台主机。比…

【无标题】程序设计和c语言-谭浩强配套(适合专升本)

一晃大半年没更新了,一直在备考,想着这几天把前段时间学的c语言给大家分享一下,在此做了一个专栏,有需要的小伙伴可私信获取。 说明:本专栏所有内容皆适合专升本复习资料,本人手上也有日常刷题整理的错题以…

电脑提示mfc140u.dll文件丢失了?怎么快速修复mfc140u.dll文件

当你的电脑提示你的mfc140u.dll文件丢失了,那么就要小心了,可能你的某些程序出问题了!这时候需要我们去进行相关的修复,只有修复了这个mfc140u.dll文件,才能正常的使用某些程序。下面一起来了解一下mfc140u.dll文件吧。…

修改ElTable组件的样式(element-plus)

效果展示 <div class"table_main"><ElTable:data"tableList":header-cell-style"{color: #ffffff,background: #6f7f93,}"class"table_border":highlight-current-row"false"><ElTableColumn type"inde…

sql注入练习

1.什么是SQL注入 SQL注入是比较常见的网络攻击方式之一&#xff0c;它不是利用操作系统的BUG来实现攻击&#xff0c;而是针对程序员编写时的疏忽&#xff0c;通过SQL语句&#xff0c;实现无账号登录&#xff0c;甚至篡改数据库 2.sql注入原理 攻击者注入一段包含注释符的SQL语…

欧鹏RHCE 第四次作业

unit4.web服务的部署及高级优化方案 1. 搭建web服务器要求如下&#xff1a; 1.web服务器的主机ip&#xff1a;172.25.254.100 2.web服务器的默认访问目录为/var/www/html 默认发布内容为default‘s page 3.站点news.timinglee.org默认发布目录为/var/www/virtual/timinglee.org…

建设智慧公厕,打造便捷、环保、安全的公共厕所使用体验

近年来&#xff0c;随着科技的快速发展&#xff0c;智慧公厕在城市建设中起到了重要的作用。通过信息化手段、智慧化管理和科技创新智能设备等措施&#xff0c;智慧公厕实现了许多令人惊叹的改变。本文将以智慧公厕源头实力厂家广州中期科技有限公司&#xff0c;大量精品案例项…