Delphi Xe10.1 reference count (Delphi Xe10.1 Berlin finally added support for Weak, unsafe)

The previous version of Delphi does not support Weak and UnSafe references of interfaces, and Weak and UnSafe of objects are supported, and it is only supported on Android and Ios platforms.

Now Delphi XE10.1 Berlin finally adds support for Weak and UnSafe interfaces.

1.Weak

Weak reference does not affect the reference counter, but if the object is released, the Weak reference variable is automatically cleared 0, look at the example:

1
2

3
4
5
6
7
8
9
10
11
12
13

14
15
16
type

< div class="line number2 index1 alt1"> TA= class code> (TInterfacedObject)

end ;

< div class="line number5 index4 alt2">

procedure TForm1< /code> . Button1Click(Sender: TObject);
var
a:IInterface;
[weak ]aweak:IInterface;
begin
a:=TA . Create; //Create an object, copy it to a, and quote counter=1 after execution
aweak:=a; //Because aweak is defined with [weak] attribute, so after assigning to aweak, the reference counter is still 1 , But the address of the aweak variable is saved in a weak association list
Memo1 . Lines . code> Add(Format( 'Ptr:%d' , [NativeInt(< /code> Pointer (aweak))]));
a:= nil ; //Since the reference counter=1, after executing this sentence, the counter is cleared to 0, the object is released, and all variables in the list are associated with this pair of weak It is also assigned a value of nil, including the aweak variable.
Memo1 . Lines . Add(Format( 'Ptr:%d' , [NativeInt( Pointer (aweak))]));
end ;

  

Run results

1
2
Ptr: 16360080
Ptr: 0

Weak reference is very It is suitable for the situation where two objects need to refer to each other. If the previous reference is used, the reference counter will not be cleared to 0.

As in the following example, after referencing each other, the counters of the two objects are unclear 0, resulting in a memory leak

1
2
3
4
5

< div class="line number6 index5 alt1 "> 6

7
8
9
10
11
12 < /div>

13
14
15
16
17
18

< div class="line number19 index18 alt2"> 19

20
21
22
23
24
25
26
27
28
29 < /div>

30
type
ISimpleInterface = interface
procedure DoSomething;
procedure AddObjectRef (simple: ISimpleInterface);
end ;
TObjectOne = class < code class="d elphi plain">(TInterfacedObject, ISimpleInterface)
private
anotherObj: ISimpleInterface;
public
procedure DoSomething;
procedure AddObjectRef (simple: ISimpleInterface);
end ;
.....................

< div class="line number16 index15 alt1">

procedure TObjectOne< /code> . AddObjectRef (simple: ISimpleInterface);
begin
anotherObj:=simple;
end ;
.....................
var

< div class="line number25 index24 alt2"> one, two: ISimpleInterface;

begin
< code class="delphi plain">one := TObjectOne . Create;
two := TObjectOne . Create;< /code>
one . AddObjectRef (two);
two . AddObjectRef (one);

At this time in Delphi XE1 0.1 Berlin can use weak reference to quickly and easily solve the leakage problem:

1
2
private
[weak] anotherObj: ISimpleInterface ;

  

2.UnSafe

Unsafe reference does not affect the reference count, but it does not clear the referenced variable like Weak reference.

1
2
3
4
5
6
7
8
9
10
11

12

13
14
15
type
TA= class (TInterfacedObject)
end ; code>
procedure TForm1 . Button2Click(Sender: TObject);
var< /code>
a:IInterface;

[unsafe]aunsafe:IInterface;
begin
/code> a:=TA . Create;
aunsafe:=a;
Memo1 . Lines . Add(Format( 'Ptr:%d' , [NativeInt( Pointer (aunsafe))])); < /div>

a:= nil ;
Memo1 . Lines . Add(Format( 'Ptr:%d' , [NativeInt( Pointer (aunsafe))]));
end ;

  

Run results

1
2
Ptr: 42640064
Ptr: 42640064

Because of the Unsafe reference, it does not affect the application counter. The following program will cause a memory leak:

< td class="gutter">

1
2
3
4
5
6 < /div>

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

< p>

1
2
3

< div class="line number4 index3 alt1"> 4

5
6
7
8
9
10
1 1
12
13
14 < /div>

15
16
type
TA= class (TInterfacedObject)< /code>
end< /code> ;
procedure TForm1 . Button1Click( Sender: TObject);
var
a:IInterface;
[weak]aweak:IInterface;
begin
a:=TA . < code class="delphi plain">Create; //Create an object, copy it to a, and quote counter=1 after execution
aweak:=a; // Since aweak defines the [weak] attribute, after assigning to aweak, the reference counter is still 1, but the address of the aweak variable is saved in a weak association list
Memo1 . Lines . Add(Format( 'Ptr :%d' , [Nati veInt( Pointer (aweak))]));
a:= nil < code class="delphi plain">; //Because the reference counter=1, after executing this sentence, the counter is cleared to 0, the object is released, and the list is associated with this pair of weak All variables in are also assigned the value nil, including the aweak variable.
Memo1 . Lines . Add(Format( 'Ptr:%d' , [NativeInt( Pointer (aweak))]));
end ;

< div class="line number1 index0 alt2"> 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
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

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 ;

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

1
2
Ptr: 16360080
Ptr: 0

1
2
Ptr: 16360080
Ptr: 0

1

2

Ptr: 16360080
Ptr: 0

Ptr: 16360080

Ptr: 0

1
2
3
4
5
6 < /div>

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);

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);

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);

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: I SimpleInterface;
begin
   one := TObjectOne . Create;
   two := TObjectOne . Create;
   one . AddObjectRef (two);
   two . AddObjectRef (one);

type

ISimpleInterface =  interface

   procedure  DoSomething;

   procedure  AddObjectRef (simple: ISimpleInterface);

end ;

 

TObjectOne =  class  (TInterfacedObject, ISimpleInterface)

private

   anotherObj: ISimpleInterface;

public

   proced ure  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);

1
2
private
   [weak] anotherObj: ISimpleInterface;

1
2
private
   [weak] anotherObj: ISimpleInterface;

1
2
private
   [weak] anotherObj: ISimpleInterface;

1

2

private
   [weak] anotherObj: ISimpleInterface;

private

   [weak] anotherObj: ISimpleInterface;

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
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;
   a unsafe:=a;
   Memo1 . Lines . Add(Format( ‘Ptr:%d‘ , [NativeInt( Pointer (aunsafe))]));
   a:= nil ;
   Memo1 . Lines . Add(Format( ‘Ptr:%d‘ , [NativeInt( Pointer (aunsafe))]));
end ;

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

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 ;

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

< tbody>

1
2
Ptr: 42640064
Ptr: 42640064

1
2
Ptr: 42640064
Ptr: 42640064

1

2

Ptr: 42640064
Ptr: 42640064

Ptr: 42640064

Ptr: 42640064

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

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

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

1

2

3

4

5

6

7

procedure  TForm1 . Button2Click(Sender: TObject); < /div>

var
   [unsafe] one: ISomeInterface;
begin
   one := TSomeObject . Create;
   one . DoSomething;
end ;

procedure  TForm1 . Button2Click(Sender: TObject);

var

   [unsafe] one: ISomeInterface;

begin

   one := TSomeObject . Create;

   one . DoSomething;

end ;

Leave a Comment

Your email address will not be published.