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 div>
3
4
5
6
7
8
9
10
11
12
13 div>
14
15
16
|
type < div class="line number2 index1 alt1"> end ; < div class="line number5 index4 alt2"> procedure TForm1< /code> 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> 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 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> begin anotherObj:=simple; end ; ..................... var < div class="line number25 index24 alt2"> 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
|
type TA= class (TInterfacedObject) end ; code> procedure TForm1 . Button2Click(Sender: TObject); var< /code> a:IInterface; div>
[unsafe]aunsafe:IInterface; begin 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:
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( (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 code> 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 . 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 . 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 |
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
;
WordPress database error: [Table 'yf99682.wp_s6mz6tyggq_comments' doesn't exist]SELECT SQL_CALC_FOUND_ROWS wp_s6mz6tyggq_comments.comment_ID FROM wp_s6mz6tyggq_comments WHERE ( comment_approved = '1' ) AND comment_post_ID = 3108 ORDER BY wp_s6mz6tyggq_comments.comment_date_gmt ASC, wp_s6mz6tyggq_comments.comment_ID ASC