Re: [Vala] use weak and var together



On Sat, 2009-01-10 at 23:48 +0100, Hans Vercammen wrote:
On Sat, 2009-01-10 at 13:07 -0500, Yu Feng wrote:
On Sat, 2009-01-10 at 18:35 +0100, Jürg Billeter wrote:
On Sat, 2009-01-10 at 12:19 -0500, Yu Feng wrote:
On Sat, 2009-01-10 at 09:24 +0100, Jürg Billeter wrote:
On Sat, 2009-01-10 at 01:04 -0500, Yu Feng wrote:
On Fri, 2008-12-12 at 08:08 +0100, Jürg Billeter wrote:
On Thu, 2008-12-11 at 23:56 -0500, Yu Feng wrote:
Talking about circular references, is it possible to have a
circular ref
breaker mechanism like the one in GTK for vala fundamental classes?

I'm not very familiar with the inner workings. But don't they explicitly
destroy the objects instead of simply unreffing like vala does?
Neither am I. GTKObject has a destroy signal to do the magic with
g_ojbect_run_dispose. Cycle references are automatically resolved. the
relavent code are in gtk/gtkobject.c but I didn't have time to study it
carefully.





I don't think we should always add a dispose mechanism to fundamental
classes. However, if someone wants to use that, it should still be
possible to implement this with a bit of extra Vala code.


I suddenly realized it is impossible to write dispose mechanism with
extra vala code because one can not override the hidden unref method,
therefore one can not do the cycle detection/breaking at the right time.

unref methods are never virtual in GObject. However, you can override
the dispose method in Vala. Is this what you meant or can you explain
what exactly you want to achieve?


No. We were talking about GTypeInstance fundamental classes in that
mail. They don't have a 'dispose' method to be overriden.

Right, but I'm not sure that you need to change anything in the unref
function to get dispose functionality working. Can you explain more
specifically what you can't get working with the current possibilities?


Yes I can do this:

class Object {
   Object ref_to_there;
   Object ref_to_here;
   private disposed = false;
   public virtual void dispose() {
         /*release references here*/
      ref_to_there = null;
      ref_to_here = null;
   }
   private void run_dispose() {
      if(disposed) return;
      disposed = true;
      dispose();
   }
   public void destroy() {
      Object holder = this; 
      /*needed if invoked from a weak reference of this*/
      run_dispose();
      holder = null;
   }
}

Then Object.destroy can be used to manifestly break any cycle
references.

Why do this manually? Don't you need to chain the dispose handlers
throughout the hierarchy to make it usable somehow?
But this is not a GObject. It's about implementing two stage disposal
and ref breaking with GTypeInstance classes.

As far as I understand the GObject dispose mechanism, it doesn't prevent
the cyclic references from not being cleaned up. But it allows you to
manually break them if they exist.
Perhaps it would be a good idea to dispose the member references in the
GObject dispose handler by default instead of the finalize handler. In
this case the user could build a custom object management system on top
of vala and call the dispose handler explicitly when required. Of course
this could cause various side-effects when not used carefully. On the
other hand so do raw pointers and preventing these memory leaks is as
far as know only possible by using weak references.

Hans






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