inline:
Quote:
> I hope you don't mind me asking you more questions. It is very
>interesting
> to hear other peoples view on things. My thougts might not be right,
>and
> then it is nice to be corrected. I have lots to learn.
Not at all, though you might want to search back in the Dec, Jan timeframe
for an extensive discussion of this topic. (There was a lot in
Microsoft.public.vb.general.discussion, including several in depth posts
from Matt Curland.)
Quote:
> About circular reference, I usually use a weak pointer to an object to
>get
> rith of those annoying helperclasses and strong references. Is this a
>bad
> methology? As long I know that the object exists or not this is,
>according
> to me, a good solution. I don't have to worry about anything when I
>release
> an object with circular reference that way. Or am I in another
>dimention now?
Nope, that's fine. The best way to release a circular reference is to not
have it in the first place <grin>. My point is that *if* you have a
circular reference a mere stand-alone set to nothing will not solve it. You
may use the actual code "Set x to Nothing" in whatever solution you use (or
you may not). But again, it isn't blind. Rather, it's a conscious design
decision made to handle the issue.
Quote:
> Do you use strong references? How do you take care of object_A
>pointing to
> object_B pointing back to object_A without a helper-class?
If I absolutely must have the circular logic, I usually use the strong
reference and then wrap all of the code in a some other component so that I
can verify that I call the "release" method. I find, however, that I only
need this kind of design every once in a blue moon. What I usually do is
factor out the "shared" data that makes the child refer to the parent. I
find that this usually models the actual problem much better. Something
like this:
' clsParent
Private m_oShared As Shared
Private m_colChildren as Collection
Public Sub Init()
Set m_oShared = New Shared
' Call code that loads or creates shared data or whatever
Set m_colChildren = New Collection
End Sub
' clsChild
Private m_oShared As Shared
Public Sub Init (ParentInfo As Shared)
Set m_oShared = ParentInfo
End Sub
Note that it doesn't really matter what "Shared" has in it. The concept is
that "Child" didn't really need to have 100% access to Parent. It isn't
going to invoke all of Parent's methods or anything like that. Once you
start thinking that way, you realize that Parent was doing two different
things--which means that it should be split into two different classes.
There's no circular reference at all here. When Parent goes out of scope,
it releases its reference to Shared and the collection of Child objects. As
each Child object goes out of scope, it releases the remaining references to
the Shared object. Naturally, the whole thing is even more useful when
Parent happens to be a class factory for the Child objects. Then you can
hide the Shared object from Clients;
' add to clsParent
Public Function Add() As Child
Dim oChild As Child
Set oChild = New Child
oChild.Init m_oShared ' Init on Child can be Friend method, for
example
m_colChildren.Add oChild
Set Add = oChild
End Function
I also occasionally use unique IDs and lookup tables. The objects hold the
key instead of the object and use the lookup table to resolve the reference
as needed. This works great when you very rarely need the parent reference.
(In fact, that's just a less performant version of a weak reference that
works dynamically with very little code or overhead when not in use.)
Quote:
>> Public Sub Something
>> Dim oThing As Thing
>> Set oThing = New Thing
>> oThing.Whatever
>> Set oThing = Nothing ' Useless
>> End Sub ' All objects that just went out of scope released by VB.
> I'm in line with you on this code. However, I don't trust the VB
>compiler
> for nothing, that is why I set it to nothing. Just in case the
>'garbage-
> collector' wouldn't work. There are no extra IDispatch calls, just a
>few
> extra clockticks for setting the pointer. That I can survive to get
>rith
> of any _possible_ memoryleaks. If i'm stupid and the compiler is
>smart,
> it will hopefully optimize it automagically.
Why don't you trust it? No one on this board has been able to come up with
a single example of code where it does not work. Matt Curland stated
categorically that it always works.
What really happens is that "blindly" setting to nothing creates the
illusion that maybe you'll *blindly* cover for a design or code flaw. As I
think I showed with the two examples in the previous post, the blind set
does not accomplish that objective.
I used to think that, so what, a few superflicious sets are not going to
hurt anything. But like any other useless code, the net effect is that
people start to believe the code is necessary or useful. Then they start to
make decisions based on it being there. For example, they start doing this:
On Error Goto Trap
Dim oThing As Thing
Set oThing = New Thing
' Do something with thing
Set oThing = Nothing
Exit Sub
Trap:
If Not (oThing Is Nothing) Then
Set oThing = Nothing
End If
Not so bad, you say? Well there also has to be the actual error handling
code in there. And The whole structure multiplies with each object and each
potential error. Pretty soon, if your consistent, you have projects full of
*totally useless code*. And as Matt Curland also explained, you can never
be 100% consistent. VB creates all kinds of temporary objects, sets them to
reference other objects, then releases them as required. For example, you
trust VB to call release on the temp variable that "With" creates for you.
The straw that breaks the camel's back is when you go to solve a real memory
leak in the above type of project. In a clean project, I can usually
eyeball it and find the circular reference. (Same kind of situation applies
to solving performance problems.) In *totally useless code*, however, there
are hundreds of lines of "release" code to scan through before the real
problem can be found.
And finally, *every* time someone on one of these boards asked how to solve
a memory leak, someone answers "make sure you set all your objects to
nothing". I have visions of all these programmers doing like a guy in our
organization and spending several days following that advice and being no
closer to solving his leak. <grin>
Steven