Jump to content
Tom F

Should I free a sub-form or does its owner do that?

Recommended Posts

Is there ever a time to explicitly free a sub-form or does it parent form always do that?

The expression:

     TForm2.Create(Self)

establishes that the sub-form TForm2 is owned by the parent form TForm1.  When TForm1 one is destroyed, the RTL will destroy TForm2?  If so, fNonModalForm.Free should never be done?
 

procedure TForm1.btnCloseAllClick(Sender: TObject);
begin
  if Assigned(fNonModalForm) then
    begin
      if fNonModalForm.Visible then
        fNonModalForm.Close;
      FreeAndNil(fNonModalForm);   // <--- Should I do this ever?
    end;
  Self.Close;
end;

procedure TForm1.btnOpenNonModalWindowClick(Sender: TObject);
begin
  if NOT Assigned(fNonModalForm) then
    fNonModalForm := TForm2.Create(Self);
  fNonModalForm.Show;
end;

 

Edited by Tom F

Share this post


Link to post

Since it was created like this from Form1:

11 minutes ago, Tom F said:

TForm2.Create(Self);

you don't need to explicitly free it--it will be freed when the owner form, Form1, is freed.

 

Sometimes, however, you want/need to manage it yourself. For example:

var
  Form3: TForm;
begin
  Form3 := TForm3.Create(nil);
  try
    // do stuff...
  finally
    Form3.Free;
  end;

This may be the case if you don't have a current form available.

Share this post


Link to post

I would say it depends on the application and the platform. When on mobile platforms, I prefer to free AND NIL forms that are not used a lot given that memory is a limited resource

Share this post


Link to post

@corneliusdavid:  Is it safe to set a form's parent to nil, as in TForm.Create(nil)?  Does a form inherit properties and behaviors from a parent that if we use nil are not inherited?

 @John Kouraklis: In some initial testing I was finding even if I explicitly did .Free and := nil (or used FreeAndNil) that the RTL still seemed to be trying to destroy the sub-form when it destroyed its parent form, the app's main form.

I'm hoping that some RTL gurus will clarify all this for us.

Share this post


Link to post

 

10 minutes ago, Tom F said:

Is it safe to set a form's parent to nil, as in TForm.Create(nil)?

Yes, I've implemented this technique many times over the years. For example, in a plugin where I don't have easy access to the main application form's handle or when I don't want a global form variable laying around for inadvertent use and just have a quick dialog form to show and destroy.

12 minutes ago, Tom F said:

Does a form inherit properties and behaviors from a parent that if we use nil are not inherited?

Someone may correct me but as far as I know, it doesn't do any more than set the Owner property; then when the owner is being freed, its destructor checks to see if the Owner is nil and if not, frees it.

 

So, if you assign it, then free it yourself, it'll try to be freed twice unless you set the Owner := nil manually. Conversely, if you don't assign it and don't free it, you'll create a memory leak. (I only mention these as things NOT to do to give more insight into what's happening.)

Share this post


Link to post

 @corneliusdavid  Thanks for the response. I hope you are correct. 

 

I hope someone who knows the internals of the RTL will post her confirming that TForm.Create(nil) has no side effects other than relieving the parent form from the responsibility of freeing the form.

Somehow I thought that Z-order (I'm using fsStayOnTop) depending on the sub-form knowing its parent.

Tom

Share this post


Link to post
20 minutes ago, Tom F said:

Is it safe to set a form's parent to nil, as in TForm.Create(nil)?

Yes. Unless you have a reason to specify an explicit owner, you should actually specify nil to make it clear (when reading the code) that there is no owner.

 

20 minutes ago, Tom F said:

Does a form inherit properties and behaviors from a parent that if we use nil are not inherited?

No. You can specify that a "child form" should be centered on the owner form (Position=poOwnerFormCenter), but it's still safe to specify nil as the owner.

 

27 minutes ago, Tom F said:

In some initial testing I was finding even if I explicitly did .Free and := nil (or used FreeAndNil) that the RTL still seemed to be trying to destroy the sub-form when it destroyed its parent form, the app's main form.

You're mistaken. There must have been something else going on.

 

4 minutes ago, corneliusdavid said:

then when the owner is being freed, its destructor checks to see if the Owner is nil and if not, frees it.

It's the same for all classes derived from TComponent; When a component is free'd it will free all the components it owns. TComponent is a base class of TForm.

  • Thanks 1

Share this post


Link to post
39 minutes ago, Tom F said:

@corneliusdavid:  Is it safe to set a form's parent to nil, as in TForm.Create(nil)?  Does a form inherit properties and behaviors from a parent that if we use nil are not inherited?
 

As others have said, it's very safe. Just don't forger to free the form.

 

39 minutes ago, Tom F said:

 @John Kouraklis: In some initial testing I was finding even if I explicitly did .Free and := nil (or used FreeAndNil) that the RTL still seemed to be trying to destroy the sub-form when it destroyed its parent form, the app's main form.
 

I don't think so. Just create a blank project and test again. 

 

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×