zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Vi/Vim查找替换使用方法【转】
    ios开发--NSDate与NSDateFormatter的相关用法【转】
    IOS开发基础之—MD5加密算法【转】
    struts2多图片上传实例【转】
    IOS开发之----常用的基本GDB命令【转】
    WWDC笔记:2011 Session 125 UITableView Changes, Tips and Tricks
    Xcode8 NSLog打印json不完整的解决方案
    Swift 3.1 的一些新特性
    iOS中书写代码规范35条小建议
    女程序员做了个梦,众网友的神回复
  • 原文地址:https://www.cnblogs.com/findumars/p/11579222.html
Copyright © 2011-2022 走看看