Delphi XE10.1 引用计数(Delphi XE10.1 Berlin终于增加了对接口的Weak, UnSafe的支持)

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

原文地址:https://www.cnblogs.com/findumars/p/11579222.html

时间: 2024-07-30 07:40:20

Delphi XE10.1 引用计数(Delphi XE10.1 Berlin终于增加了对接口的Weak, UnSafe的支持)的相关文章

Delphi XE10.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:

QPointer,QSharedPointer,QWeakPointer的区别与使用例子(QSharedPointer类似Delphi里的引用计数,是强引用,而QWeakPointer是弱引用,不影响原始对象的引用计数,相当于是在暗中观察对象,但保持联系,需要的时候就会出现)

QPointer is a template class that provides guarded pointers to Qt objects and behaves like a normal C++ pointer except that it is automatically set to 0 when the referenced object is destroyed and no "dangling pointers" are produced.QSharedPoint

Andorid Binder进程间通信---Binder本地对象,实体对象,引用对象,代理对象的引用计数

本文参考<Android系统源代码情景分析>,作者罗升阳. 一.Binder库(libbinder)代码: ~/Android/frameworks/base/libs/binder ----BpBinder.cpp ----Parcel.cpp ----ProcessState.cpp ----Binder.cpp ----IInterface.cpp ----IPCThreadState.cpp ----IServiceManager.cpp ----Static.cpp ~/Androi

引用计数智能指针

<a>C++ <span style="font-family:宋体;">智能指针具体解释</span></a> 一.简单介绍 因为 C++ 语言没有自己主动内存回收机制.程序猿每次 new 出来的内存都要手动 delete. 程序猿忘记 delete.流程太复杂.终于导致没有 delete.异常导致程序过早退出,没有运行 delete 的情况并不罕见. 用智能指针便能够有效缓解这类问题,本文主要解说參见的智能指针的使用方法.包含:std

Android实例-Delphi开发蓝牙官方实例解析(XE10+小米2+小米5)

Android实例-Delphi开发蓝牙官方实例解析(XE10+小米2+小米5) 相关资料:1.http://blog.csdn.net/laorenshen/article/details/411498032.http://www.cnblogs.com/findumars/p/5149128.html 一.理清概念1.蓝牙设备:是指代有蓝牙通信的手机.电脑.平板.打印机.耳机等.2.设备名称:是指设备打开蓝牙功能后,在其他设备中显示的名字,如图1用的A.B.C等.3.蓝牙关态:如果A手机没有

实现类似shared_ptr的引用计数

13.27 定义使用引用计数版本的HasPtr #include<iostream> #include<string> #include<new> using namespace std; class HasPtr { public: HasPtr(const string &s=string()):ps(new string(s)),i(0),use(new size_t(1)) {cout<<"constructer"<

深拷贝&amp;浅拷贝&amp;引用计数&amp;写时拷贝

(1).浅拷贝: class String { public: String(const char* str="") :_str(new char[strlen(str)+1]) { strcpy(_str,str); } ~String() { if(NULL!=_str) { delete[] _str; _str=NULL; } } private: char* _str; }; int main() { String s1("hello"); String

手工引用计数中规则

使用设值方法为属性赋值时 assign.retain.copy三个特性的实现 self.property = newValue; assign的特性会是这样: property = newValue; retain特性会是这样 if (property!=0) { [property release]; property = [newValue retain]; } copy的特性会是这样 if (property!=0) { [property release]; property = [ne

Objective-C中的引用计数

导言 Objective-C语言使用引用计数来管理内存,也就是说,每个对象都有个可以递增或递减的计数器.如果想使某个对象继续存活,那就递增其引用计数:用完了之后,就递减其计数.计数为0,就表示没人关注此对象了,于是,就可以把它销毁. 从Mac OS X 10.8开始,“垃圾收集器”(garbage collector)已经正式废弃了,以Objective-C代码编写Mac OS X程序时不应再使用它,而iOS则从未支持过垃圾收集.因此,掌握引用计数机制对于学好Objective-C来说十分重要.