Re: GObjectClass.dispose and bringing objects back to life



On Mon, Dec 5, 2011 at 3:20 AM, Benjamin Otte <otte gnome org> wrote:
> I would be somewhat tempted to listen to all the stuff you're saying
> below. But then I looked at the code you maintain[1], and I realized
> it doesn't do anything of that. So I'm inclined to think that what
> you're talking about is more about an ideal world that you wish we all
> aspired to, but is not in any way related to how people write code in
> the real world.

Ok let's do rant then

>
> Benjamin
>
> 1: http://git.gnome.org/browse/gnumeric/tree/gnumeric.doap
>
>
> On Sun, Dec 4, 2011 at 3:15 PM, Morten Welinder <mortenw gnome org> wrote:
>>> What we probably also should do is deprecate one of the two
>>> virtual functions, so people use the same one to clean up everywhere.
>>
>> That would be a _really_ bad idea.
>>
>> _finalize gets rid of the last fragments of the object.  Since random
>> code could have obtained refs to the object, the object designer
>> can generally not control when this happens.
>>
>> _dispose has two functions: (1) break reference cycles by getting
>> rid of as many objects as it can, and (2) getting rid of externally-
>> visible parts of the object and subobjects it owns.
>>
>> (2) tells you why you can't merge the two methods.  Widgets,
>> for example, really need to go away from the screen when you
>> tell them, not whenever something else decides to release a ref.
>> Objects that have open files really need to close them at dispose
>> time, not next Wednesday.
>>
>> Gtk1 didn't have dispose in name, but it had the destroy method
>> instead.  Same thing.
>>
>>> [...] we [...] know that trying to support objects functioning
>>> after dispose is like trying to make your code handle
>>> NULL returns
>>
>> I don't think we know that, not do I think it's true.
>>
>> Making _dispose work really comes down to following one
>> simple rule: after _dispose, the object should be as well defined
>> as it was after _init.  I.e., anything you free you set to NULL
>> and you don't free anything that was allocated in _init[*].

He has a point here, except most code doesn't follow this rule
because *so much* code (GTK+ code, even) goes ahead and
over-allocates resources in the _init() step.

Much of that code should actually be happening in the
GObjectClass.constructor() instead of _init()... code for instance
which does: gtk_container_add(self, new_widget)

Of course all of that code which (naively) assumes that
GtkContainerClass has finished initializing will break the moment that
GtkContainerClass decides to (withing it's own rights) not function until
finished initializing in the ->constructor().

Of course GtkContainer wont do that (as specially since so much
"broken" code depends on it not changing), but many widgets
have use of construct-time assigned properties at initialization time.

Hence the rule: Don't access parent class's apis at all until ->constructor()
runs and you know that the parent class is actually ready.

Even if we assume that everybody hates construct-only properties (who's
usage cause the above rule to be even more essential), and go to the
pain of handling every api prematurely (from child class's _init() function),
then we run a high risk of doing things twice at initialization time
and significantly
slowing down widget hierarchy creation cycles.

I.e.:
 o  Parent Class has api called from child class's _init() function
 o  Parent Class initializes resources prematurely, due to premature api access
 o  Later during object construction, a property is set
 o  That property setting causes the same resource to be
re-initialized in a different 'mode'

In summary, if most code was written with a 2 step, "safe"
initialization, it would
resemble much more what Morten is describing, only initial property states and
various caches (delegate arrays/queues/hash tables) would be setup at
_init() time,
which is all you really want to get rid of at ->finalize time.

Cheers,
         -Tristan

>>
>> M.
>>
>>
>> [*] Unless you allocate a new dummy object to put in its place.
>> That wouldn't make much sense unless you have big trouble
>> with circular references.
> _______________________________________________
> gtk-devel-list mailing list
> gtk-devel-list gnome org
> http://mail.gnome.org/mailman/listinfo/gtk-devel-list


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]