假设我的Delphi类看起来像这样:
interface
type
TMySubInfo = class
public
Name : string;
Date : TDateTime;
Age : Integer;
end;
TMyInfo = class
public
Name : string;
SubInfo : array of TMySubInfo;
destructor Destroy; override;
end;
implementation
destructor TMyInfo.Destroy;
begin
// hmmm..
end;
end.
要正确清理,析构函数应该包含哪些内容?是SetLength(SubInfo,0)
是否足够,或者我是否需要循环并释放每个TMySubInfo
?我是否需要做任何事情?
答案 0 :(得分:12)
你需要循环并释放每个创建的对象。
您必须知道,声明一个TMySubInfo数组实际上并不创建对象。你必须稍后创建它们。
我会使用TList代替更动态的方法。您甚至可以使用一个TObjectList,它可以在列表被释放时释放所有项目。
答案 1 :(得分:9)
您应该释放每个项目,例如
destructor TMyInfo.Destroy;
var
I: Integer;
begin
for I:= Low(SubInfo) to High(SubInfo) do
SubInfo[I].Free;
SetLength(SubInfo, 0);
inherited;
end;
答案 2 :(得分:6)
您可以按照分配对象的方式释放对象。如果通过调用类的构造函数来指定元素的值,则释放该元素引用的对象。
destructor TMyInfo.Destroy;
var
info: TMySubInfo;
begin
for info in SubInfo do
info.Free;
inherited;
end;
使用Delphi 2005中引入的语法。如果您有旧版本,请使用显式循环控制变量:
var
i: Integer;
begin
for i := 0 to High(SubInfo) do
SubInfo[i].Free;
您最后无需致电SetLength
。当对象被销毁时,像SubInfo
这样的动态数组字段会自动释放。它的作用与interface,string和Variant字段相同。
答案 3 :(得分:5)
同意上述所有建议,但我想添加一个(诚然有点肛门)推荐,你总是调用FreeAndNil()程序而不是Free方法。
迟早你会不小心访问已经释放的对象。如果您有FreeAndNil-ing的习惯,那么您可以在包含问题的行上立即获得a / v。如果你只是释放了这个物体,你可能会在一段时间后得到一个神秘的,显然没有连接的失败......
这可能在析构函数的上下文中看起来很痴迷,就像这里一样。好的,它有点,但是无论是在任何地方还是根本没有。
答案 4 :(得分:4)
它也是肛门,但喜欢以与创作相反的顺序释放,例如:
For I := List.Count-1 downto 0 do
List[I].Free;
我认为创造和毁灭是作为parethesis(),尽管它使得实际的执行差异变得微不足道。 BRI
答案 5 :(得分:3)
如果您通过构造函数调用创建了对象,则需要调用Free来释放它们。如果没有,你就不会。
答案 6 :(得分:2)
对于每一个新的应该是免费的。
答案 7 :(得分:0)
你能否使用Finalize?