加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Delphi XE10.1 引用计数

发布时间:2020-12-15 09:55:57 所属栏目:大数据 来源:网络整理
导读:以往的Delphi版本,不支持接口的Weak,和UnSafe的引用,支持对象的Weak,UnSafe,而且仅在Android和Ios平台上支持。 现在Delphi XE10.1 Berlin终于增加了对接口的Weak,UnSafe的支持。 ? 1.Weak Weak引用,不影响引用计数器,但是如果对象被释放,Weak引用变量

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

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

?

1.Weak

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

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,导致内存泄漏

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引用,来快速方便的解决泄漏问题:

private

?? [weak] anotherObj: ISimpleInterface;
?

2.UnSafe

?

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

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;

运行结果

Ptr: 42640064
Ptr: 42640064

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

procedure TForm1.Button2Click(Sender: TObject);
var
  [unsafe] one: ISomeInterface;
begin
  one := TSomeObject.Create;
  one.DoSomething;
end;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读