[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