以往的Delphi版本,不支持接口的Weak,和UnSafe的引用,支持对象的Weak, UnSafe,而且仅在Android和Ios平台上支持。

现在Delphi XE10.1 Berlin终于增加了对接口的Weak, UnSafe的支持。

1.Weak

Weak引用,不影响引用计数器,但是如果对象被释放,Weak引用变量自动清0,来看例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
type
  TA=class(TInterfacedObject)
 
  end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  a:IInterface;
  [weak]aweak:IInterface;
begin
  a:=TA.Create;   //创建对象,复制给a,执行完成后引用计数器=1
  aweak:=a;       //由于aweak定义有[weak]属性,所以赋值给aweak后,引用计数器依旧为1,但aweak变量的地址被保存到一个weak关联列表中
  Memo1.Lines.Add(Format('Ptr:%d', [NativeInt(Pointer(aweak))]));
  a:=nil;         //由于引用计数器=1,执行此句后,计数器清0,对象被释放,同时与此对weak关联列表中所有变量也被赋值为nil,包括aweak变量.
  Memo1.Lines.Add(Format('Ptr:%d', [NativeInt(Pointer(aweak))]));
end;

  

运行结果

1
2
Ptr:16360080
Ptr:0

weak引用非常适合用于两个对象需要互相引用的情况下,如果以往的引用,将无法让引用计数器清0.

如下面的例子,互相引用后,两个对象的计数器都不清0,导致内存泄漏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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;
 
.....................
 
procedure TObjectOne.AddObjectRef (simple: ISimpleInterface);
begin
  anotherObj:=simple;
end;
 
.....................
 
var
  one, two: ISimpleInterface;
begin
  one := TObjectOne.Create;
  two := TObjectOne.Create;
  one.AddObjectRef (two);
  two.AddObjectRef (one);

这时候在Delphi XE10.1 Berlin下可以用weak引用,来快速方便的解决泄漏问题:

1
2
private
  [weak] anotherObj: ISimpleInterface;

  

2.UnSafe

unsafe引用,不影响引用计数,但不会向Weak引用那样清零引用的变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type
  TA=class(TInterfacedObject)
 
  end;
procedure TForm1.Button2Click(Sender: TObject);
var
  a:IInterface;
  [unsafe]aunsafe:IInterface;
begin
  a:=TA.Create;
  aunsafe:=a;
  Memo1.Lines.Add(Format('Ptr:%d', [NativeInt(Pointer(aunsafe))]));
  a:=nil;
  Memo1.Lines.Add(Format('Ptr:%d', [NativeInt(Pointer(aunsafe))]));
end;

  

运行结果

1
2
Ptr:42640064
Ptr:42640064

由于Unsafe引用,不影响应用计数器,下面的程序将导致内存泄漏:

1
2
3
4
5
6
7
procedure TForm1.Button2Click(Sender: TObject);
var
  [unsafe] one: ISomeInterface;
begin
  one := TSomeObject.Create;
  one.DoSomething;
end;

  

https://www.cnblogs.com/hezihang/p/5536928.html#undefined

最新文章

  1. UOJ59 WC2013 小Q运动季
  2. zigbee学习之路(十三):基于协议栈的Usart 实验
  3. Jquery页面初始化的4种方式
  4. Roguelike 相关知识
  5. ModernUI教程:主题资源引用
  6. Spring 一二事(4) - 单例
  7. 布局两列div等高方法
  8. cocos2d-x学习之类型转换(转)
  9. Hibernate事务传播性
  10. 100M 宽带办理
  11. hdu4858 项目管理 bestcoder round1 B
  12. Android源码编译jar包BUILD_JAVA_LIBRARY 与BUILD_STATIC_JAVA_LIBRARY的区别(二)
  13. C++遍历二维数组的四种方法
  14. Android事件分发回传机制
  15. [原创]基于Zybo SDIO WiFi模块调试
  16. SVN-您的主机中的软件中止了一个已建立的连接
  17. HTML 介绍及标签
  18. 数据库面试题之COUNT(*),COUNT(字段),CONUT(DISTINCT 字段)的区别
  19. Linux Centos下安装jdk
  20. 【Django】关于使用阿里的iconfont

热门文章

  1. Generalized Intersection over Union: A Metric and A Loss for Bounding Box Regression
  2. Prometheus磁盘监控
  3. MongoDB数据表添加字段
  4. 关于Image模块的调色板
  5. (一)IDEA修改HTML不生效(未热部署)
  6. C#获取IP及MAC地址 方法
  7. 【Leetcode_easy】917. Reverse Only Letters
  8. DevOps - DevOps精要 - 溯源
  9. adb(Andorid Debug Bridge)安装和使用
  10. social engineering toolkit