Re: Newbie question about release, freeAndNil, etc



swansnow wrote:
ok. I suspect this is a newbie question, hence the subject line. Be
nice to me :)

(I'm using Delphi 6, btw)

When you create a Form, Delphi gives you a global variable to use. We
actually use them,

Please reconsider. Unless your forms are all singletons, those global variables will only get you into trouble, eventually.


Delphi declares those for you for convenience in the RAD world, where all the forms are auto-created. Go ahead and delete those global declarations.

The main form needs to have a variable declaration so that Application.CreateForm has something to populate for its second parameter. Go ahead and move the main form's global variable declaration into your DPR file. That way, you won't be tempted to use it anywhere else in your program.

so in our code we have things like:

i.e., in a button click handler:
if not assigned(frmViewerOptions) then
   frmViewerOptions := TFrmViewerOptions.create(application);
frmViewerOptions.showModal;

etc

What is the recommended way of freeing these forms?

I recommend you free modal dialogs when ShowModal returns. That means you have code like this:


LViewerOptions := TFrmViewerOptions.Create(nil);
try
  LViewerOptions.ShowModal;
finally
  LViewerOptions.Free;
end;

(LViewerOptions is a local variable.)

We have several
variations:

1)
frmViewerOptions.showModal;
//stuff
freeAndNil(frmViewerOptions);
----
2)
frmViewerOptions.showModal;
//stuff
frmViewOptions.release;
frmViewerOptions := nil;

Those two are fine.

3)
frmViewerOptions.showModal;
//stuff
frmViewOptions.release;
freeAndNil(frmViewerOptions);

That will always lead to access violations or other exceptions.

4)
in the FormClose handler of the form (TFrmViewerOptions):
action := caFree;
frmViewerOptions := nil;

That's OK, although I dislike using caFree because it means the code that created the form is no longer the same as the code that's responsible for freeing it. I prefer to keep those responsibilities in the same place. The thing that creates the form should be the thing that frees it, too.


This is where you'll run into problems with forms that aren't singletons. The entire form class is assuming that the reference to every instance of itself will always be stored in the same single variable.

5)
in the FormClose handler of the form:
release;
frmViewerOptions := nil;

If you're going to call Release in the OnClose handler, then you should instead just set Action to caFree. They amount to the same things, most of the time, but the idiomatic way is to use caFree.


--
Rob
.