Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

RELEASE myObject does not call myObject's Destroy

Status
Not open for further replies.

DirkVFP

Programmer
Aug 25, 2005
57
NL
Hi all,

I have a custom made class "myClass" which contains a function which will show a search form or close it if the search form is already open:
Code:
	PROCEDURE Search		
		IF VARTYPE(This.m_oSearchForm) = "O" THEN 
			This.m_oSearchForm.Release
		ELSE 
			DO FORM ".\forms\search" WITH This NAME This.m_oSearchForm NOSHOW 
			This.m_oSearchForm.Show(0) 	
		ENDIF 
	ENDPROC

My main form uses the class in the following manner (Form's Init method):
Code:
PUBLIC myObject
myObject = CREATEOBJECT("myClass")

Whenever a user hits the 'search' button on the main form I issue
Code:
myObject.Search
If the search form is open it will be closed and vice versa.

What I want is: when the user closes the main form I want to close search form (that is, if it is open).
In my main form I do the following in its Destroy event:
Code:
RELEASE myObject

I put a Destroy procedure in myClass which should handle this:
Code:
	PROCEDURE Destroy	
		*** If search form is still open, close it.
		IF VARTYPE(This.m_oSearchForm) = "O" THEN 			
			This.m_oSearchForm.Release
		ENDIF 
	ENDPROC
And here's where my problem occurs: the myClass.Destroy event is only called if the search form is already released OR if I close the VFP7 environment! So it seems to me that, if an object still holds any references, its Destroy won't be called untill all references are gone.

Is this normal behaviour? Or am I missing a point here?
 
Dirk,

I had a similar problem -- see thread1254-1250563.

This is normal behaviour. Essentially, you can't release an object if it holds a reference to another object. As you've noticed, in those circumstances, the main object's Destroy doesn't even fire.

My solution was to convert my main object from a Custom to a Container, and then programmatically remove the contained referred-to object.

In your case, it's a little different. Because the object you are trying to destroy is a form, you must remove the reference to the referred-to object (the search form) before the main form's Destroy is executed.

Your code is correct:

Code:
IF VARTYPE(This.m_oSearchForm) = "O" THEN             
  This.m_oSearchForm.Release
ENDIF

But you should execute this explicitly in your Close button (before you call THISFORM.Release). You also need to execute it in the main form's QueryUnload(), in case the user closes the form from the X button in the title bar (or by closing the entire app). Either way, the search form will have closed before you reach the main form's Destroy, so all should be well.

It might also be a good idea to set THIS.m_oSearchForm to NULL, although I'm not sure if that's really necessary.

Hope this helps.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
DirkVP,

If I understand well you are creating the object in the init of a form?
PUBLIC myObject
myObject = CREATEOBJECT("myClass")
In that case It might make sense to have a custom property added to the form as reference i.s.o. a global var.

Assuming you have an added property called SearchForm
the code in the init should be this.searchform = createobject('myclass')

-Bart
 
In addition:
I do use this technique so that once the mainform is closed also the reference to your searchform is removed.
I assume that's your goal though?
-Bart
 
Mike,

Thanks for your help. I've been playing around and came up with another solution. I've created a Close method which I call explicitly in my main form's Destroy event:
Code:
myObject.Close
RELEASE myObject

*** Release other resources

The myObject.Close method is, in fact, my old Destroy method.
This way I'm keeping al my cleaning up code in one method, namely the main form's Destroy event. It keeps my code clear ;)
 
Bart,

Your suggestion to make the object reference a property of my main form is more OOP, I will implement that.
Code:
this.searchform = createobject('myclass')
This won't work, since my class isn't a form an sich. The search form is but a part of it.
 
Dirk,

I've created a Close method which I call explicitly in my main form's Destroy event:

I'm slightly surprised that works. Given that, in your original code, the Destroy wasn't getting called, I would have thought that your custom Close method wouldn't get called either. Still, if it works ....

By the way, I agree with Bart about using a form property rather than a public variable, but it's not really relevant to your present problem.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

My Visual FoxPro site: www.ml-consult.co.uk
 
Given that, in your original code, the Destroy wasn't getting called...

My main form's Destroy was always called, it was the myObject's Destroy method that did not receive any calls if it contained any references.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top