zoukankan      html  css  js  c++  java
  • 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.
  • 相关阅读:
    系统兼容性与软件兼容性
    SqlServer 笔记三 规则
    Sql Server 2008 与 Visual Studio 2008 安装说明
    Ms Sql Server
    Git系列教程三 配置与基本命令
    Git系列教程一 入门与简介
    Git系列教程二 基础介绍
    浏览器IE与非IE区分
    SqlServer 笔记二 获取汉字的拼音首字母
    时间戳与日期字符串的转换
  • 原文地址:https://www.cnblogs.com/del88/p/6875738.html
Copyright © 2011-2022 走看看