可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Suppose my Delphi classes look like this:
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.
To properly clean up, what should go in the destructor? Is it enough to do SetLength(SubInfo,0)
, or do I need to loop through and free each TMySubInfo
? Do I need to do anything at all?
回答1:
You need to loop through and free each created object.
You must know, that declaring a array of TMySubInfo doesn't actually create the objects. You have to create them later on.
I would use a TList instead for a more dynamic approach. You could even use a TObjectList that can free all its items when the list gets freed.
回答2:
You should free each item, like this
destructor TMyInfo.Destroy;
var
I: Integer;
begin
for I:= Low(SubInfo) to High(SubInfo) do
SubInfo[I].Free;
SetLength(SubInfo, 0);
inherited;
end;
回答3:
You free the objects the same way you allocated them. If you assigned an element's value by calling the constructor of a class, then free the object referenced by that element.
destructor TMyInfo.Destroy;
var
info: TMySubInfo;
begin
for info in SubInfo do
info.Free;
inherited;
end;
That uses syntax introduced in Delphi 2005. If you have an older version, use an explicit loop-control variable:
var
i: Integer;
begin
for i := 0 to High(SubInfo) do
SubInfo[i].Free;
You don't need to call SetLength
at the end. A dynamic-array field like SubInfo
gets released automatically when the object is destroyed. It works the same as interface, string, and Variant fields.
回答4:
Agreed with all the above suggestions, but I want to add an (admittedly somewhat anal) recommendation that you always call the FreeAndNil() procedure in preference to the Free method.
Sooner or later you will accidentally access an object that you have already freed. If you have the habit of FreeAndNil-ing everything, then you get an immediate a/v on the line that contains the problem. If you merely Free'd the object, you will likely get a mysterious and apparently unconnected failure some time later...
This might seem obsessive in the context of a destructor, as here. Ok, it is a bit, but either one does it everywhere or not at all.
回答5:
It is also anal, but Like to free in the reverse order to the creation, for example:
For I := List.Count-1 downto 0 do
List[I].Free;
I view creation and destruction as parethesis () although it makes litte actual execution diference.
Bri
回答6:
If you created the objects via constructor calls, you need to make calls to Free to free them. If not, you don't.
回答7:
For every new there should be a free.
回答8:
Can you not use Finalize?