Ale żeście się rozgadali. Po pierwsze jak duskutować o samoczynnym zwalnianiu, to pasowało by nadmienić jakich klas to dotyczy w przypadku Delphi - ktoś gotów pomyśleć że nie trzeba zwalniać np TStringList. A więc dotyczy to pochodnych TComponent (za helpem):
...
For components created programmatically, that is, not created in the form designer, call Create and pass in an owner components the AOwner parameter. The owner disposes of the component when it is destroyed. If the component is not owned, then use Free when it needs to be destroyed.
...
Po drugie, po co podawać jakieś skomplikowane przykłady skoro wystarczy prosty test:
Kopiuj
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TTest = class (TComponent)
private
fName : String;
public
constructor Create(aOwner : TComponent; aName : String);
destructor Destroy; override;
end;
var
Form1: TForm1;
t1, t2 : TTest;
implementation
{$R *.DFM}
{ TTest }
constructor TTest.Create(aOwner: TComponent; aName : String);
begin
inherited Create(aOwner);
fName := aName;
end;
destructor TTest.Destroy;
begin
Application.MessageBox(PChar(fName + ' jest zwalniany'), nil, 0);
inherited;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
t1 := TTest.Create(Application, 'Application');
t2 := TTest.Create(nil, 'Bez ownera');
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
// t2.Free; // przy zakomentowanej linijce będzie wyciek pamięci
end;
end.
To tyle dla potwierdzenia słów jednego z was. Jak to działa, to jedna sprawa są jeszcze inne aspekty. To że coś jest automatycznie zwalniane OK, pytanie tylko czy jesteśmy świadomi kiedy ... i przykład książkowy:
"a gdyby tu było przedszkole w przyszłości ... i kontruktor alokował by bitmapę dwu-megową" - to by sobie żyła aż aplikacja/forma się nie zamknie, bez względu na to czy była by potrzeba czy nie.
Dlatego też IMHO najlepiej jest przyjąć zasadę tworzymy-zwalniamy, a konkretnie
t := ttest.create();
try
...
finally
freeandnil(t)
end;
Tak jest po prostu czytelniej. Wiem jest więcej kodu - ale IMHO tak jest lepiej.
Aha ktoś tam napisał że coś jest automatycznie inicjowane. Otóż w przypadku zmiennych globalnych czy pól klas OK, ale w przypadku zmiennych lokalnych (czy Integer, czy pochodnych TObject) - FALSE !!! Sprawdźcie sami jak nie wierzycie. Podstawowa zasada przy używaniu zmienych lokalnych jest taka żeby nadać im początkową wartość !!! Zresztą, jak ktoś czasem zwraca uwagę przed czym kompilator nas ostrzega, to tego typu informacja właśnie się tam znajdzie.
Pozdro