bob*_*ski 3 delphi dictionary memory-leaks tdictionary
我实现了以下类:
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;
Run Code Online (Sandbox Code Playgroud)
然后我有一个全局变量:
procedures: TDictionary<string, TCallback>;
Run Code Online (Sandbox Code Playgroud)
在OnFormActivate
程序I初始化procedures
变量:
procedures := TDictionary<string, TCallback>.Create();
procedures.Add('something', TCallback.Create('sth', @proc, 'annotation'));
// ....
Run Code Online (Sandbox Code Playgroud)
然后在OnFormClose
我释放它:
procedures.Clear;
procedures.Free;
Run Code Online (Sandbox Code Playgroud)
我的代码是否泄漏内存?如果是这样,什么是正确的释放方式dictionary
?据我所知,迭代不是好主意.
代码泄漏内存,因为a TDictionary
中包含的对象不会自动释放.
如果需要将对象存储在字典中,采用TObjectDictionary代表了一种更好的方法.
如果希望自动释放字典中包含的对象,请doOwnsValues
在创建集合实例时使用该标志.
当变量确实是全球性(即下申报var
的interface
单位的部分),应该创建,并在破坏initialization
和finalization
单位本身的部分.
. . .
var
procedures: TObjectDictionary<string, TCallback>;
. . .
initialization
procedures:= TObjectDictionary<string, TCallback>.Create([doOwnsValues]);
finalization
procedures.Free;
Run Code Online (Sandbox Code Playgroud)当您的变量属于表单类本身时,您应该在表单的OnCreate
事件中创建字典.
. . .
public
procedures: TObjectDictionary<string, TCallback>;
. . .
procedure TForm1.FormCreate(Sender: TObject);
begin
procedures:= TObjectDictionary<string, TCallback>.Create([doOwnsValues]);
end;
Run Code Online (Sandbox Code Playgroud)
在表单的OnDestroy
活动中释放字典:
procedure TForm1.FormDestroy(Sender: TObject);
begin
procedures.Free;
end;
Run Code Online (Sandbox Code Playgroud)此外,如果您希望访问属于该类的变量而无需类本身的实例(这在许多编程语言中称为静态变量),您可以将字典声明为a class var
并可选择通过它来访问它一个class property
; 在这种情况下,最好在中class constructor
和中创建和销毁集合class destructor
.
. . .
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;
Run Code Online (Sandbox Code Playgroud)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;
Run Code Online (Sandbox Code Playgroud)
作为旁注,TCallback
该类不需要指定析构函数,因为它只拥有两个字符串和一个指向过程的指针.因此默认的析构函数继承自TObject
足够的.