See
And have a look at the implementation:
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;
Examples
Consider the following code:
procedure TForm1.FormCreate(Sender: TObject);
var
bm: TBitmap;
begin
bm := TBitmap.Create;
bm.LoadFromFile('C:UsersAndreas RejbrandDocumentsRAD Studio6.0DemosDelphiWin32VCLWin32Footballup.bmp');
bm.Free;
if Assigned(bm) then
bm.SaveToFile('C:UsersAndreas RejbrandDesktopest.bmp')
else
ShowMessage('Cannot save! The bitmap does no longer exist!');
end;
This will create an error or an invalid (empty) bitmap on my desktop, because I try to use an object that has been freed. Yes, even though bm
has been freed, it is still "assigned", i.e. bm
still points to a memory adress, even though there is nothing (usable) there. To overcome this, one can set bm := nil
, as a safeguard, Then assigned(bm)
will return false, as one would want. More or less, FreeAndNil(bm)
is a shorthand for bm.Free; bm := nil
. The first statement frees all memory (and OS resources, CPU time etc. used by the object), and bm := nil
sets the "pointer" bm
to nil
, so that bm
no longer points to the place where the object used to be, but no longer is. This way you (and routines like assigned
) will not get fooled to believe that there still is a bitmap object.
Discussion
Some say that you should always use FreeAndNil(foo)
rather than foo.Free
. Well, why not? The additional instruction foo := nil
will probably not take too many nanoseconds to execute, and indeed assigned(foo) = false
is a very nice property of a freed object. But then again, if you know what you are doing, and know that you will never use the foo
object again after freeing it, then you could stick to just foo.free
. Really, some would argue that in many cases (but not all), trying to use a variable of a freed object is a bug by itself. (Of course there are cases where you do this intentionally - you have an object foo
that sometimes is assigned and sometimes is not.)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…