程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi XE10.1 引用計數,delphixe10.1

Delphi XE10.1 引用計數,delphixe10.1

編輯:Delphi

Delphi XE10.1 引用計數,delphixe10.1


 

以往的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;

  

運行結果

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;

  

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved