gpt4 book ai didi

Delphi 字典释放

转载 作者:行者123 更新时间:2023-12-03 15:44:50 26 4
gpt4 key购买 nike

我实现了以下类:

type
TUtilProcedure = procedure(var AJsonValue: TJSONObject);

TCallback = class
private
FName: string;
FProcedure: TUtilProcedure;
FAnnotation: string;
public
constructor Create(AName: string; AProcedure: TUtilProcedure; AAnnotation: string); overload;
constructor Create(ACallback: TCallback); overload;
property Name: string read FName;
property Proc: TUtilProcedure read FProcedure;
property Annotation: string read FAnnotation;
end;

然后我有一个全局变量:

procedures: TDictionary<string, TCallback>;

OnFormActivate 过程中,我初始化 procedures 变量:

procedures := TDictionary<string, TCallback>.Create();
procedures.Add('something', TCallback.Create('sth', @proc, 'annotation'));
// ....

然后在OnFormClose中我释放它:

procedures.Clear;
procedures.Free;

我的代码是否泄漏内存?如果是这样,释放字典的正确方法是什么?据我所知,迭代并不是一个好主意。

最佳答案

代码会泄漏内存,因为 TDictionary 中包含的对象不会自动释放。

如果需要在字典中存储对象,则采用TObjectDictionary代表了一种更好的方法。

如果您希望自动释放字典中包含的对象,请在创建集合实例时使用 doOwnsValues 标志。

  • 当变量确实是全局的(即在单元的 interface 部分的 var 下声明)时,它应该在单元本身的初始化终结部分中创建和销毁。

    . . .
    var
    procedures: TObjectDictionary<string, TCallback>;
    . . .
    initialization
    procedures:= TObjectDictionary<string, TCallback>.Create([doOwnsValues]);
    finalization
    procedures.Free;
  • 当您的变量属于表单类本身时,您应该在表单的 OnCreate 事件中创建字典。

    . . .
    public
    procedures: TObjectDictionary<string, TCallback>;
    . . .
    procedure TForm1.FormCreate(Sender: TObject);
    begin
    procedures:= TObjectDictionary<string, TCallback>.Create([doOwnsValues]);
    end;

    在表单的 OnDestroy 事件中释放字典:

    procedure TForm1.FormDestroy(Sender: TObject);
    begin
    procedures.Free;
    end;
  • 此外,如果您希望访问属于该类的变量而不需要类本身的实例(这在许多编程语言中称为静态变量) ,您可以将字典声明为 class var 并可以选择通过 class property 访问它;在这种情况下,最好在类构造函数类析构函数中创建和销毁集合。

    . . .
    TMyClass = class
    private
    class constructor Create;
    class destructor Destoy;
    public
    class var procedures: TObjectDictionary<string, TCallback>;
    end;
    . . .
    class constructor TMyClass.Create;
    begin
    procedures := TObjectDictionary<string, TCallback>.Create([doOwnsValues]);
    end;

    class destructor TMyClass.Destoy;
    begin
    procedures.Free;
    end;
<小时/>
TCallback = class
private
FName: string;
FProcedure: TUtilProcedure;
FAnnotation: string;
public
constructor Create(AName: string; AProcedure: TUtilProcedure; AAnnotation: string); overload;
constructor Create(ACallback: TCallback); overload;
property Name: string read FName;
property Proc: TUtilProcedure read FProcedure;
property Annotation: string read FAnnotation;
end;

顺便说一句,TCallback 类不需要指定析构函数,因为它只拥有两个字符串和一个指向过程的指针。因此从 TObject 继承的默认析构函数就足够了。

关于Delphi 字典释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32221454/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com