TDictionary 与 TObjectDictionary

TDictionary 与 TObjectDictionary 的区别是 : TObjectDictionary 可以做到 free的时候 里面的对象 一并free,从而不会出现内存 泄露。

用途: 

TDictionary 适合 内存自管理的东西 如:integer int64 word string 结构体  与 动态数组(基本类型与结构体)。如下用法:

TObjectDictionary<string, RPerson>.create();

TObjectDictionary 适合 对象 等内存 手动管理的东西,一般就是 对象。如下用法:

可以发现它有三个构造函数;ACapacity 的意思是 构造的时候 首先创建几个对象。就是说 静态的创建映射类。可以做到映射类创建的时候 事先就内置几个 对象。

Ownerships 的意思是 key或value 跟随 字典一并释放,是个集合参数,那么可以集合为空 或 key 或 key+value 或 value 4种情况。

空集合的时候 表示 key 和 value 都不跟随字典一并释放,需要手工释放。

doOwnsKeys ---- 表示key 跟随字典一并释放。

doOwnsValues --- 表示value 跟随字典一并释放。

demo如下,可以参见:

unit Unit5;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Generics.Collections;

type
  TForm5 = class(TForm)
    Memo1: TMemo;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TPerson = class
    public
      name: string;
      age: Integer;
  end;

var
  Form5: TForm5;

implementation

{$R *.dfm}

procedure TForm5.Button2Click(Sender: TObject);
var
  map: TObjectDictionary<string, TPerson>;
  map2: TObjectDictionary<TObject, TPerson>;
  keyStr: string;
  tempButton: TObject;
begin
  //这么写会报错,因为key是string类型的内存释放自管理的, 不能交由字典来管理, 值是object类型的可以
  //map := TObjectDictionary<string, TPerson>.Create([doOwnsKeys,doOwnsValues]);
  map := TObjectDictionary<string, TPerson>.Create([doOwnsValues]);

  //注意这里就得写 doOwnsKeys,doOwnsValues] 了,因为key 与 value 都是 对象, 要想map2释放的时候 key与value连同释放就得如此
  map2 := TObjectDictionary<TObject, TPerson>.Create([doOwnsKeys, doOwnsValues]);
  try
    map.Add('11', TPerson.Create);
    map.Add('22', TPerson.Create);
    map['11'].name := '小李飞刀';
    map['22'].name := '火云邪神';

    for keyStr in map.Keys do
    begin
      Memo1.Lines.Add(keyStr + '------' + map[keyStr].name );
    end;



    map2.Add(TButton.Create(nil), TPerson.Create);
    map2.Add(TButton.Create(nil), TPerson.Create);
    for tempButton in map2.Keys do
    begin
      TButton(tempButton).Top := Random(200);
      TButton(tempButton).Left := Random(200);
      TButton(tempButton).Caption := '测试';
      TButton(tempButton).Parent := Self;

    end;
    Application.ProcessMessages;
    Sleep(4000) ; // 注意观察 button 会 4秒后 消失。
  finally
    map.Free;
    map2.Free;
  end;
end;

procedure TForm5.FormCreate(Sender: TObject);
begin
  ReportMemoryLeaksOnShutdown := True;
end;

end.
原文地址:https://www.cnblogs.com/del88/p/6875738.html