[Kde-bindings] playground/bindings/kimono

Arno Rehn arno at arnorehn.de
Tue Mar 6 17:48:27 UTC 2007

Am Dienstag, 6. März 2007 schrieb Richard Dale:
> On Tuesday 06 March 2007, Arno Rehn wrote:
> > Am Montag, 5. März 2007 schrieb Richard Dale:
> > > So the 'internalPointer' has a different value even when the underlying
> > > instance is the same. That's because QAbstractItemModel.CreateIndex()
> > > allocates a new GCHandle every time, which will have different values.
> > > The reason it works in QtRuby is because the internalPointer is a Ruby
> > > VALUE that is  the same for every createIndex call.
> >
> > Ah tanks. I added a Dictionary where all the GCHandles for QModelIndex'es
> > are stored. This GCHandle is looked up for the specific QModelIndex and
> > then passed to the C++ helper function. Selecting child items is no
> > problem anymore. Up to now I thought GCHandle.Alloc() returns always the
> > same value, but apparently it doesn't.
> I thought about have a WeakReference as a key, but I don't think that works
> because wrapping an instance in a GCHandle will probably create a strong
> reference (you wouldn't want an instance to be GC'd while you were
> referencing it in C code).
Yes, that's right, but than we just need to change the WeakReference to a 
normal, 'strong' reference.

> So I think you need to have the actual object as a key, and a struct as a
> value with two fields; a reference count and a GCHandle. When you add a new
> GCHandle, set the ref count to 1 and increment every time the handle is
> reused in another QModelIndex. Then in the QModelIndex destructor, retrieve
> the entry for the wrapped object and decrement the ref count. If the ref
> count is then zero, delete the entry.
That won't work, I think, because the destructor is only called automatically, 
when the object is GC'd. And as long as there is a strong reference, the 
object won't be GC'd, so the destrcutor is never called. Hence, the only case 
in which a destructor is called is when you have something like
using (QModelIndex index = CreateIndex(...)) {
	// code
After that the instance is gone, and then it wouldn't make sense anymore to 
decrement some counter, because the instance was deleted anyway.

I think the current way is OK, because we can easily check if the instance is 
still alive (e.g. in the above example with using(...) {...} it may have been 
deleted) and if not, we can just delete the entry in the Dictionary. The 
WeakReference is just as good as a strong reference for this kind of doings 
and provides us with IsAlive a useful property.

Arno Rehn
arno at arnorehn.de

More information about the Kde-bindings mailing list